sui_jsonrpc/msgs/
dynamic_field.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3use std::fmt::Display;
4
5use serde::{Deserialize, Serialize};
6use serde_with::{DisplayFromStr, IfIsHumanReadable, serde_as};
7use sui_sdk_types::{Address, Digest, Identifier, StructTag, TypeTag, Version};
8
9use super::Page;
10use crate::serde::Base64orBase58;
11
12const DYNAMIC_FIELD_MODULE_NAME: &str = "dynamic_field";
13const DYNAMIC_FIELD_FIELD_STRUCT_NAME: &str = "Field";
14
15const DYNAMIC_OBJECT_FIELD_MODULE_NAME: &str = "dynamic_object_field";
16const DYNAMIC_OBJECT_FIELD_WRAPPER_STRUCT_NAME: &str = "Wrapper";
17
18pub type DynamicFieldPage = Page<DynamicFieldInfo, Address>;
19
20/// Originally `sui_types::dynamic_field::DynamicFieldName`.
21#[serde_as]
22#[derive(Clone, Serialize, Deserialize, Debug)]
23#[serde(rename_all = "camelCase")]
24pub struct DynamicFieldName {
25    #[serde_as(as = "IfIsHumanReadable<DisplayFromStr, _>")]
26    pub type_: TypeTag,
27    #[serde_as(as = "IfIsHumanReadable<_, DisplayFromStr>")]
28    pub value: serde_json::Value,
29}
30
31impl Display for DynamicFieldName {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        write!(f, "{}: {}", self.type_, self.value)
34    }
35}
36
37/// Originally `sui_types::dynamic_field::DynamicFieldInfo`.
38#[serde_as]
39#[derive(Clone, Serialize, Deserialize, Debug)]
40#[serde(rename_all = "camelCase")]
41pub struct DynamicFieldInfo {
42    pub name: DynamicFieldName,
43    #[serde_as(as = "IfIsHumanReadable<Base64orBase58, _>")]
44    pub bcs_name: Vec<u8>,
45    pub type_: DynamicFieldType,
46    pub object_type: String,
47    pub object_id: Address,
48    pub version: Version,
49    pub digest: Digest,
50}
51
52impl DynamicFieldInfo {
53    pub fn is_dynamic_field(tag: &StructTag) -> bool {
54        tag.address == Address::TWO
55            && tag.module.as_str() == DYNAMIC_FIELD_MODULE_NAME
56            && tag.name.as_str() == DYNAMIC_FIELD_FIELD_STRUCT_NAME
57    }
58
59    pub fn is_dynamic_object_field_wrapper(tag: &StructTag) -> bool {
60        tag.address == Address::TWO
61            && tag.module.as_str() == DYNAMIC_OBJECT_FIELD_MODULE_NAME
62            && tag.name.as_str() == DYNAMIC_OBJECT_FIELD_WRAPPER_STRUCT_NAME
63    }
64
65    pub fn dynamic_field_type(key: TypeTag, value: TypeTag) -> StructTag {
66        StructTag {
67            address: Address::TWO,
68            name: Identifier::from_static(DYNAMIC_FIELD_FIELD_STRUCT_NAME),
69            module: Identifier::from_static(DYNAMIC_FIELD_MODULE_NAME),
70            type_params: vec![key, value],
71        }
72    }
73
74    pub fn dynamic_object_field_wrapper(key: TypeTag) -> StructTag {
75        StructTag {
76            address: Address::TWO,
77            module: Identifier::from_static(DYNAMIC_OBJECT_FIELD_MODULE_NAME),
78            name: Identifier::from_static(DYNAMIC_OBJECT_FIELD_WRAPPER_STRUCT_NAME),
79            type_params: vec![key],
80        }
81    }
82}
83
84/// Originally `sui_types::dynamic_field::DynamicFieldType`.
85#[derive(Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq, Debug)]
86pub enum DynamicFieldType {
87    #[serde(rename_all = "camelCase")]
88    DynamicField,
89    DynamicObject,
90}
91
92impl Display for DynamicFieldType {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        match self {
95            DynamicFieldType::DynamicField => write!(f, "DynamicField"),
96            DynamicFieldType::DynamicObject => write!(f, "DynamicObject"),
97        }
98    }
99}