iota_graphql_rpc/types/
move_struct.rs1use async_graphql::*;
6use iota_package_resolver::{DataDef, MoveData};
7
8use crate::{
9 error::Error,
10 types::{
11 iota_address::IotaAddress,
12 move_module::MoveModule,
13 open_move_type::{MoveAbility, OpenMoveType, abilities},
14 },
15};
16
17pub(crate) struct MoveStruct {
18 defining_id: IotaAddress,
19 module: String,
20 name: String,
21 abilities: Vec<MoveAbility>,
22 type_parameters: Vec<MoveStructTypeParameter>,
23 fields: Vec<MoveField>,
24 checkpoint_viewed_at: u64,
25}
26
27#[derive(SimpleObject)]
28pub(crate) struct MoveStructTypeParameter {
29 pub(crate) constraints: Vec<MoveAbility>,
30 pub(crate) is_phantom: bool,
31}
32
33#[derive(SimpleObject)]
35#[graphql(complex)]
36pub(crate) struct MoveField {
37 pub(crate) name: String,
38 #[graphql(skip)]
39 pub(crate) type_: OpenMoveType,
40}
41
42#[Object]
44impl MoveStruct {
45 pub(crate) async fn module(&self, ctx: &Context<'_>) -> Result<MoveModule> {
47 let Some(module) = MoveModule::query(
48 ctx,
49 self.defining_id,
50 &self.module,
51 self.checkpoint_viewed_at,
52 )
53 .await
54 .extend()?
55 else {
56 return Err(Error::Internal(format!(
57 "Failed to load module for struct: {}::{}::{}",
58 self.defining_id, self.module, self.name,
59 )))
60 .extend();
61 };
62
63 Ok(module)
64 }
65
66 pub(crate) async fn name(&self) -> &str {
68 &self.name
69 }
70
71 pub(crate) async fn abilities(&self) -> Option<&Vec<MoveAbility>> {
73 Some(&self.abilities)
74 }
75
76 pub(crate) async fn type_parameters(&self) -> Option<&Vec<MoveStructTypeParameter>> {
80 Some(&self.type_parameters)
81 }
82
83 pub(crate) async fn fields(&self) -> Option<&Vec<MoveField>> {
87 Some(&self.fields)
88 }
89}
90
91#[ComplexObject]
92impl MoveField {
93 #[graphql(name = "type")]
94 async fn type_(&self) -> Option<&OpenMoveType> {
95 Some(&self.type_)
96 }
97}
98
99impl MoveStruct {
100 pub(crate) fn new(
101 module: String,
102 name: String,
103 def: DataDef,
104 checkpoint_viewed_at: u64,
105 ) -> Result<Self, Error> {
106 let type_parameters = def
107 .type_params
108 .into_iter()
109 .map(|param| MoveStructTypeParameter {
110 constraints: abilities(param.constraints),
111 is_phantom: param.is_phantom,
112 })
113 .collect();
114
115 let MoveData::Struct(fields) = def.data else {
116 return Err(Error::Internal(format!(
119 "Expected struct data, but got: {:?}",
120 def.data
121 )));
122 };
123 let fields = fields
124 .into_iter()
125 .map(|(name, signature)| MoveField {
126 name,
127 type_: signature.into(),
128 })
129 .collect();
130
131 Ok(MoveStruct {
132 defining_id: IotaAddress::from(def.defining_id),
133 module,
134 name,
135 abilities: abilities(def.abilities),
136 type_parameters,
137 fields,
138 checkpoint_viewed_at,
139 })
140 }
141}