sui_graphql_rpc/types/
move_struct.rsuse async_graphql::*;
use sui_package_resolver::{DataDef, MoveData};
use crate::error::Error;
use super::{
move_module::MoveModule,
open_move_type::{abilities, MoveAbility, OpenMoveType},
sui_address::SuiAddress,
};
pub(crate) struct MoveStruct {
defining_id: SuiAddress,
module: String,
name: String,
abilities: Vec<MoveAbility>,
type_parameters: Vec<MoveStructTypeParameter>,
fields: Vec<MoveField>,
checkpoint_viewed_at: u64,
}
#[derive(SimpleObject)]
pub(crate) struct MoveStructTypeParameter {
pub(crate) constraints: Vec<MoveAbility>,
pub(crate) is_phantom: bool,
}
#[derive(SimpleObject)]
#[graphql(complex)]
pub(crate) struct MoveField {
pub(crate) name: String,
#[graphql(skip)]
pub(crate) type_: OpenMoveType,
}
#[Object]
impl MoveStruct {
pub(crate) async fn module(&self, ctx: &Context<'_>) -> Result<MoveModule> {
let Some(module) = MoveModule::query(
ctx,
self.defining_id,
&self.module,
self.checkpoint_viewed_at,
)
.await
.extend()?
else {
return Err(Error::Internal(format!(
"Failed to load module for struct: {}::{}::{}",
self.defining_id, self.module, self.name,
)))
.extend();
};
Ok(module)
}
pub(crate) async fn name(&self) -> &str {
&self.name
}
pub(crate) async fn abilities(&self) -> Option<&Vec<MoveAbility>> {
Some(&self.abilities)
}
pub(crate) async fn type_parameters(&self) -> Option<&Vec<MoveStructTypeParameter>> {
Some(&self.type_parameters)
}
pub(crate) async fn fields(&self) -> Option<&Vec<MoveField>> {
Some(&self.fields)
}
}
#[ComplexObject]
impl MoveField {
#[graphql(name = "type")]
async fn type_(&self) -> Option<&OpenMoveType> {
Some(&self.type_)
}
}
impl MoveStruct {
pub(crate) fn new(
module: String,
name: String,
def: DataDef,
checkpoint_viewed_at: u64,
) -> Result<Self, Error> {
let type_parameters = def
.type_params
.into_iter()
.map(|param| MoveStructTypeParameter {
constraints: abilities(param.constraints),
is_phantom: param.is_phantom,
})
.collect();
let MoveData::Struct(fields) = def.data else {
return Err(Error::Internal(format!(
"Expected struct data, but got: {:?}",
def.data
)));
};
let fields = fields
.into_iter()
.map(|(name, signature)| MoveField {
name,
type_: signature.into(),
})
.collect();
Ok(MoveStruct {
defining_id: SuiAddress::from(def.defining_id),
module,
name,
abilities: abilities(def.abilities),
type_parameters,
fields,
checkpoint_viewed_at,
})
}
}