1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! Rust types for the Move IDL specification.

mod error;
pub use error::*;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
pub use struct_tag::*;

/// A set of modules.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IDLPackage {
    /// Name of the package.
    pub name: String,
    /// Modules.
    pub modules: BTreeMap<ModuleIdData, IDLModule>,
    /// Aliases of addresses.
    pub aliases: BTreeMap<String, AccountAddressData>,
    /// Dependent modules.
    pub dependencies: BTreeMap<ModuleIdData, IDLModule>,
    /// Error map.
    pub errors: IDLErrorMapping,
    /// All structs.
    pub structs: Vec<IDLStruct>,
}

/// A struct with types.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
pub struct IDLStructType {
    /// Fully qualified name of the struct.
    pub name: StructTagData,
    /// Type arguments of the struct, if applicable.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub ty_args: Vec<IDLType>,
}

/// Simplified ABI for a Move module.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IDLModule {
    /// The module name and address.
    pub module_id: ModuleIdData,
    /// Documentation.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub doc: Option<String>,
    /// Functions.
    pub functions: Vec<IDLScriptFunction>,
    /// Structs.
    pub structs: Vec<IDLStruct>,
    /// Errors.
    pub errors: BTreeMap<u64, IDLError>,
}

/// A type represented in the IDL.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum IDLType {
    Bool,
    U8,
    U64,
    U128,
    Address,
    Signer,
    /// The number represents the index of the type parameter within the parent struct.
    TypeParam(u16),

    Tuple(Vec<IDLType>),
    Vector(Box<IDLType>),
    Struct(IDLStructType),
}

/// An `Ability` classifies what operations are permitted for a given type
#[repr(u8)]
#[derive(
    Debug, Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum IDLAbility {
    /// Allows values of types with this ability to be copied, via CopyLoc or ReadRef
    Copy = 0x1,
    /// Allows values of types with this ability to be dropped, via Pop, WriteRef, StLoc, Eq, Neq,
    /// or if left in a local when Ret is invoked
    /// Technically also needed for numeric operations (Add, BitAnd, Shift, etc), but all
    /// of the types that can be used with those operations have Drop
    Drop = 0x2,
    /// Allows values of types with this ability to exist inside a struct in global storage
    Store = 0x4,
    /// Allows the type to serve as a key for global storage operations: MoveTo, MoveFrom, etc.
    Key = 0x8,
}

fn is_false(b: impl std::borrow::Borrow<bool>) -> bool {
    !b.borrow()
}

/// A struct type parameter.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
pub struct IDLTypeParam {
    /// Name of the parameter.
    pub name: String,
    /// Whether or not this parameter is a phantom type.
    #[serde(default, skip_serializing_if = "is_false")]
    pub is_phantom: bool,
}

/// A struct.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
pub struct IDLStruct {
    /// Fully qualified name of the struct.
    pub name: StructTagData,
    /// Documentation.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub doc: Option<String>,
    /// List of struct fields.
    pub fields: Vec<IDLField>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub type_params: Vec<IDLTypeParam>,
    /// Abilities.
    pub abilities: BTreeSet<IDLAbility>,
}

/// A struct.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
pub struct IDLField {
    /// Name of the field.
    pub name: String,
    /// Documentation.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub doc: Option<String>,
    /// Type of the IDL field.
    pub ty: IDLType,
}

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IDLArgument {
    /// Name of the argument.
    pub name: String,
    /// Type of the argument.
    pub ty: IDLType,
}

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IDLScriptFunction {
    /// Name of the script function.
    pub name: String,
    /// Documentation for the script function.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub doc: Option<String>,
    pub ty_args: Vec<String>,
    pub args: Vec<IDLArgument>,
}