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