iota_graphql_rpc/types/
move_function.rs1use async_graphql::*;
6use iota_package_resolver::FunctionDef;
7
8use crate::{
9 error::Error,
10 types::{
11 iota_address::IotaAddress,
12 move_module::MoveModule,
13 open_move_type::{MoveAbility, MoveVisibility, OpenMoveType, abilities},
14 },
15};
16
17pub(crate) struct MoveFunction {
18 package: IotaAddress,
19 module: String,
20 name: String,
21 visibility: MoveVisibility,
22 is_entry: bool,
23 type_parameters: Vec<MoveFunctionTypeParameter>,
24 parameters: Vec<OpenMoveType>,
25 return_: Vec<OpenMoveType>,
26 checkpoint_viewed_at: u64,
27}
28
29#[derive(SimpleObject)]
30pub(crate) struct MoveFunctionTypeParameter {
31 constraints: Vec<MoveAbility>,
32}
33
34#[Object]
36impl MoveFunction {
37 async fn module(&self, ctx: &Context<'_>) -> Result<MoveModule> {
39 let Some(module) =
40 MoveModule::query(ctx, self.package, &self.module, self.checkpoint_viewed_at)
41 .await
42 .extend()?
43 else {
44 return Err(Error::Internal(format!(
45 "Failed to load module for function: {}::{}::{}",
46 self.package, self.module, self.name,
47 )))
48 .extend();
49 };
50
51 Ok(module)
52 }
53
54 async fn name(&self) -> &str {
56 &self.name
57 }
58
59 async fn visibility(&self) -> Option<&MoveVisibility> {
61 Some(&self.visibility)
62 }
63
64 async fn is_entry(&self) -> Option<bool> {
66 Some(self.is_entry)
67 }
68
69 async fn type_parameters(&self) -> Option<&Vec<MoveFunctionTypeParameter>> {
74 Some(&self.type_parameters)
75 }
76
77 async fn parameters(&self) -> Option<&Vec<OpenMoveType>> {
80 Some(&self.parameters)
81 }
82
83 #[graphql(name = "return")]
87 async fn return_(&self) -> Option<&Vec<OpenMoveType>> {
88 Some(&self.return_)
89 }
90}
91
92impl MoveFunction {
93 pub(crate) fn new(
94 package: IotaAddress,
95 module: String,
96 name: String,
97 def: FunctionDef,
98 checkpoint_viewed_at: u64,
99 ) -> Self {
100 let type_parameters = def
101 .type_params
102 .into_iter()
103 .map(|constraints| MoveFunctionTypeParameter {
104 constraints: abilities(constraints),
105 })
106 .collect();
107
108 let parameters = def.parameters.into_iter().map(OpenMoveType::from).collect();
109 let return_ = def.return_.into_iter().map(OpenMoveType::from).collect();
110
111 MoveFunction {
112 package,
113 module,
114 name,
115 visibility: def.visibility.into(),
116 is_entry: def.is_entry,
117 type_parameters,
118 parameters,
119 return_,
120 checkpoint_viewed_at,
121 }
122 }
123
124 pub(crate) async fn query(
125 ctx: &Context<'_>,
126 address: IotaAddress,
127 module: &str,
128 function: &str,
129 checkpoint_viewed_at: u64,
130 ) -> Result<Option<Self>, Error> {
131 let Some(module) = MoveModule::query(ctx, address, module, checkpoint_viewed_at).await?
132 else {
133 return Ok(None);
134 };
135
136 module.function_impl(function.to_string())
137 }
138}