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