sui_rpc_api/grpc/v2/move_package_service/
conversions.rs1use crate::{Result, RpcError};
10use move_binary_format::file_format::{
11 Ability as MoveAbility, AbilitySet as MoveAbilitySet, DatatypeTyParameter,
12 Visibility as MoveVisibility,
13};
14use sui_package_resolver::{DataDef, FunctionDef, MoveData, VariantDef};
15use sui_rpc::proto::sui::rpc::v2::{
16 Ability, DatatypeDescriptor, FieldDescriptor, FunctionDescriptor, Module, OpenSignature,
17 OpenSignatureBody, TypeParameter, VariantDescriptor, datatype_descriptor::DatatypeKind,
18 function_descriptor::Visibility, open_signature::Reference,
19 open_signature_body::Type as SignatureType,
20};
21use sui_types::base_types::ObjectID;
22
23pub fn convert_error(e: sui_package_resolver::error::Error) -> RpcError {
24 RpcError::new(tonic::Code::Internal, e.to_string())
25}
26
27pub fn convert_datatype(
28 datatype_name: &str,
29 data_def: &DataDef,
30 package_id: &ObjectID,
31 module_name: &str,
32) -> DatatypeDescriptor {
33 let type_parameters = data_def
34 .type_params
35 .iter()
36 .map(convert_type_parameter)
37 .collect();
38 let abilities = convert_ability_set(data_def.abilities);
39
40 let (kind, fields, variants) = match &data_def.data {
41 MoveData::Struct(fields) => {
42 let proto_fields = fields
43 .iter()
44 .enumerate()
45 .map(|(pos, (name, sig))| {
46 let mut message = FieldDescriptor::default();
47 message.name = Some(name.clone());
48 message.position = Some(pos as u32);
49 message.r#type = Some(convert_open_signature_body(sig));
50 message
51 })
52 .collect();
53 (DatatypeKind::Struct, proto_fields, vec![])
54 }
55 MoveData::Enum(variants) => {
56 let proto_variants = variants
57 .iter()
58 .enumerate()
59 .map(|(pos, variant)| convert_variant(pos, variant))
60 .collect();
61 (DatatypeKind::Enum, vec![], proto_variants)
62 }
63 };
64
65 let mut message = DatatypeDescriptor::default();
66 message.type_name = Some(format!(
67 "{}::{}::{}",
68 package_id.to_canonical_string(true),
69 module_name,
70 datatype_name
71 ));
72 message.defining_id = Some(data_def.defining_id.to_canonical_string(true));
73 message.module = Some(module_name.to_string());
74 message.name = Some(datatype_name.to_string());
75 message.abilities = abilities;
76 message.type_parameters = type_parameters;
77 message.kind = Some(kind as i32);
78 message.fields = fields;
79 message.variants = variants;
80 message
81}
82
83pub fn convert_module(
84 module_name: &str,
85 resolved_module: &sui_package_resolver::Module,
86 package_id: &ObjectID,
87) -> Result<Module> {
88 let mut datatypes = Vec::new();
89 for datatype_name in resolved_module.datatypes(None, None) {
90 let data_def = resolved_module
91 .data_def(datatype_name)
92 .map_err(convert_error)?
93 .unwrap_or_else(|| {
94 panic!(
95 "datatype {} does not have a data_def. This shouldn't happen.",
96 datatype_name
97 )
98 });
99
100 let descriptor = convert_datatype(datatype_name, &data_def, package_id, module_name);
101 datatypes.push(descriptor);
102 }
103
104 let mut functions = Vec::new();
105 for func_name in resolved_module.functions(None, None) {
106 let func_def = resolved_module
107 .function_def(func_name)
108 .map_err(convert_error)?
109 .unwrap_or_else(|| {
110 panic!(
111 "function {} does not have a function_def. This shouldn't happen.",
112 func_name
113 )
114 });
115
116 let descriptor = convert_function(func_name, &func_def);
117 functions.push(descriptor);
118 }
119
120 let mut message = Module::default();
121 message.name = Some(module_name.to_string());
122 message.datatypes = datatypes;
123 message.functions = functions;
124 Ok(message)
125}
126
127pub fn convert_function(function_name: &str, func_def: &FunctionDef) -> FunctionDescriptor {
128 let visibility = match func_def.visibility {
129 MoveVisibility::Private => Visibility::Private,
130 MoveVisibility::Public => Visibility::Public,
131 MoveVisibility::Friend => Visibility::Friend,
132 };
133
134 let type_parameters = func_def
135 .type_params
136 .iter()
137 .map(|abilities| {
138 let mut message = TypeParameter::default();
139 message.constraints = convert_ability_set(*abilities);
140 message
141 })
142 .collect();
143
144 let parameters = func_def
145 .parameters
146 .iter()
147 .map(convert_open_signature)
148 .collect();
149 let returns = func_def
150 .return_
151 .iter()
152 .map(convert_open_signature)
153 .collect();
154
155 let mut message = FunctionDescriptor::default();
156 message.name = Some(function_name.to_string());
157 message.visibility = Some(visibility as i32);
158 message.is_entry = Some(func_def.is_entry);
159 message.type_parameters = type_parameters;
160 message.parameters = parameters;
161 message.returns = returns;
162 message
163}
164
165fn convert_type_parameter(tp: &DatatypeTyParameter) -> TypeParameter {
166 let mut message = TypeParameter::default();
167 message.constraints = convert_ability_set(tp.constraints);
168 message.is_phantom = Some(tp.is_phantom);
169 message
170}
171
172fn convert_ability_set(abilities: MoveAbilitySet) -> Vec<i32> {
173 let mut result = Vec::new();
174
175 if abilities.has_ability(MoveAbility::Copy) {
176 result.push(Ability::Copy as i32);
177 }
178 if abilities.has_ability(MoveAbility::Drop) {
179 result.push(Ability::Drop as i32);
180 }
181 if abilities.has_ability(MoveAbility::Store) {
182 result.push(Ability::Store as i32);
183 }
184 if abilities.has_ability(MoveAbility::Key) {
185 result.push(Ability::Key as i32);
186 }
187
188 result
189}
190
191fn convert_variant(position: usize, variant: &VariantDef) -> VariantDescriptor {
192 let fields = variant
193 .signatures
194 .iter()
195 .enumerate()
196 .map(|(pos, (name, sig))| {
197 let mut message = FieldDescriptor::default();
198 message.name = Some(name.clone());
199 message.position = Some(pos as u32);
200 message.r#type = Some(convert_open_signature_body(sig));
201 message
202 })
203 .collect();
204
205 let mut message = VariantDescriptor::default();
206 message.name = Some(variant.name.clone());
207 message.position = Some(position as u32);
208 message.fields = fields;
209 message
210}
211
212fn convert_open_signature(sig: &sui_package_resolver::OpenSignature) -> OpenSignature {
213 let reference = sig.ref_.map(|r| match r {
214 sui_package_resolver::Reference::Immutable => Reference::Immutable as i32,
215 sui_package_resolver::Reference::Mutable => Reference::Mutable as i32,
216 });
217
218 let mut message = OpenSignature::default();
219 message.reference = reference;
220 message.body = Some(convert_open_signature_body(&sig.body));
221 message
222}
223
224fn convert_open_signature_body(
225 body: &sui_package_resolver::OpenSignatureBody,
226) -> OpenSignatureBody {
227 let (type_enum, type_name, type_params, type_param_idx) = match body {
228 sui_package_resolver::OpenSignatureBody::Bool => (SignatureType::Bool, None, vec![], None),
229 sui_package_resolver::OpenSignatureBody::U8 => (SignatureType::U8, None, vec![], None),
230 sui_package_resolver::OpenSignatureBody::U16 => (SignatureType::U16, None, vec![], None),
231 sui_package_resolver::OpenSignatureBody::U32 => (SignatureType::U32, None, vec![], None),
232 sui_package_resolver::OpenSignatureBody::U64 => (SignatureType::U64, None, vec![], None),
233 sui_package_resolver::OpenSignatureBody::U128 => (SignatureType::U128, None, vec![], None),
234 sui_package_resolver::OpenSignatureBody::U256 => (SignatureType::U256, None, vec![], None),
235 sui_package_resolver::OpenSignatureBody::Address => {
236 (SignatureType::Address, None, vec![], None)
237 }
238 sui_package_resolver::OpenSignatureBody::Vector(inner) => {
239 let inner_body = convert_open_signature_body(inner.as_ref());
240 (SignatureType::Vector, None, vec![inner_body], None)
241 }
242 sui_package_resolver::OpenSignatureBody::Datatype(key, args) => {
243 let type_name = format!(
244 "{}::{}::{}",
245 key.package.to_canonical_string(true),
246 key.module,
247 key.name
248 );
249
250 let type_args = args.iter().map(convert_open_signature_body).collect();
251 (SignatureType::Datatype, Some(type_name), type_args, None)
252 }
253 sui_package_resolver::OpenSignatureBody::TypeParameter(idx) => {
254 (SignatureType::Parameter, None, vec![], Some(*idx as u32))
255 }
256 };
257
258 let mut message = OpenSignatureBody::default();
259 message.r#type = Some(type_enum as i32);
260 message.type_name = type_name;
261 message.type_parameter_instantiation = type_params;
262 message.type_parameter = type_param_idx;
263 message
264}