sui_indexer_alt_jsonrpc/api/move_utils/
response.rs1use anyhow::anyhow;
5use move_binary_format::file_format::Ability;
6use move_binary_format::file_format::AbilitySet;
7use move_binary_format::file_format::Visibility;
8use sui_json_rpc_types::SuiMoveAbility;
9use sui_json_rpc_types::SuiMoveAbilitySet;
10use sui_json_rpc_types::SuiMoveNormalizedFunction;
11use sui_json_rpc_types::SuiMoveNormalizedType;
12use sui_json_rpc_types::SuiMoveVisibility;
13use sui_package_resolver::FunctionDef;
14use sui_package_resolver::OpenSignature;
15use sui_package_resolver::OpenSignatureBody;
16use sui_package_resolver::Reference;
17use sui_types::Identifier;
18use sui_types::base_types::ObjectID;
19
20use crate::api::move_utils::error::Error;
21use crate::context::Context;
22use crate::error::RpcError;
23use crate::error::invalid_params;
24
25pub(super) async fn function(
27 ctx: &Context,
28 package: ObjectID,
29 module: &str,
30 name: &str,
31) -> Result<SuiMoveNormalizedFunction, RpcError<Error>> {
32 use Error as E;
33
34 if !Identifier::is_valid(module) {
35 return Err(invalid_params(E::BadIdentifier(module.to_owned())));
36 }
37
38 if !Identifier::is_valid(name) {
39 return Err(invalid_params(E::BadIdentifier(name.to_owned())));
40 }
41
42 let sig = ctx
43 .package_resolver()
44 .function_signature(*package, module, name)
45 .await
46 .map_err(|e| {
47 use sui_package_resolver::error::Error as PRE;
48 match &e {
49 PRE::NotAPackage(_)
52 | PRE::PackageNotFound(_)
53 | PRE::ModuleNotFound(_, _)
54 | PRE::FunctionNotFound(_, _, _) => invalid_params(E::NotFound(e)),
55
56 PRE::TooManyTypeNodes(_, _)
59 | PRE::TooManyTypeParams(_, _)
60 | PRE::TypeParamNesting(_, _) => invalid_params(E::ResolutionLimit(e)),
61
62 PRE::Bcs(_)
64 | PRE::Store { .. }
65 | PRE::DatatypeNotFound(_, _, _)
66 | PRE::Deserialize(_)
67 | PRE::EmptyPackage(_)
68 | PRE::LinkageNotFound(_)
69 | PRE::NoTypeOrigin(_, _, _)
70 | PRE::NotAnIdentifier(_)
71 | PRE::TypeArityMismatch(_, _)
72 | PRE::TypeParamOOB(_, _)
73 | PRE::UnexpectedReference
74 | PRE::UnexpectedSigner
75 | PRE::UnexpectedError(_)
76 | PRE::ValueNesting(_) => {
77 RpcError::from(anyhow!(e).context("Failed to resolve type layout"))
78 }
79 }
80 })?;
81
82 Ok(normalized_function(&sig))
83}
84
85fn normalized_function(sig: &FunctionDef) -> SuiMoveNormalizedFunction {
86 SuiMoveNormalizedFunction {
87 visibility: visibility(sig.visibility),
88 is_entry: sig.is_entry,
89 type_parameters: sig.type_params.iter().map(|a| ability_set(*a)).collect(),
90 parameters: sig.parameters.iter().map(normalized_signature).collect(),
91 return_: sig.return_.iter().map(normalized_signature).collect(),
92 }
93}
94
95fn normalized_signature(sig: &OpenSignature) -> SuiMoveNormalizedType {
96 use SuiMoveNormalizedType as T;
97
98 let body = normalized_type(&sig.body);
99 match sig.ref_ {
100 Some(Reference::Immutable) => T::Reference(Box::new(body)),
101 Some(Reference::Mutable) => T::MutableReference(Box::new(body)),
102 None => body,
103 }
104}
105
106fn normalized_type(sig: &OpenSignatureBody) -> SuiMoveNormalizedType {
107 use OpenSignatureBody as S;
108 use SuiMoveNormalizedType as T;
109 match sig {
110 S::Address => T::Address,
111 S::Bool => T::Bool,
112 S::U8 => T::U8,
113 S::U16 => T::U16,
114 S::U32 => T::U32,
115 S::U64 => T::U64,
116 S::U128 => T::U128,
117 S::U256 => T::U256,
118 S::Vector(sig) => T::Vector(Box::new(normalized_type(sig))),
119 S::Datatype(t, params) => T::new_struct(
120 t.package.to_canonical_string(true),
121 t.module.to_string(),
122 t.name.to_string(),
123 params.iter().map(normalized_type).collect(),
124 ),
125 S::TypeParameter(ix) => T::TypeParameter(*ix),
126 }
127}
128
129fn visibility(v: Visibility) -> SuiMoveVisibility {
130 match v {
131 Visibility::Public => SuiMoveVisibility::Public,
132 Visibility::Friend => SuiMoveVisibility::Friend,
133 Visibility::Private => SuiMoveVisibility::Private,
134 }
135}
136
137fn ability_set(a: AbilitySet) -> SuiMoveAbilitySet {
138 SuiMoveAbilitySet {
139 abilities: a.into_iter().map(ability).collect(),
140 }
141}
142
143fn ability(a: Ability) -> SuiMoveAbility {
144 match a {
145 Ability::Copy => SuiMoveAbility::Copy,
146 Ability::Drop => SuiMoveAbility::Drop,
147 Ability::Store => SuiMoveAbility::Store,
148 Ability::Key => SuiMoveAbility::Key,
149 }
150}