1#![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))]
2
3use std::error::Error as StdError;
15use std::fmt::Debug;
16
17#[cfg(feature = "derive")]
18pub use moverox_traits_derive::MoveDatatype;
19use moverox_types::{Address, IdentStr, Identifier, StructTag, TypeTag};
20
21#[cfg(feature = "derive")]
22#[doc(hidden)]
23pub mod external;
24mod primitives;
25mod vector;
26
27pub use self::primitives::{
28 AddressTypeTag,
29 BoolTypeTag,
30 U8TypeTag,
31 U16TypeTag,
32 U32TypeTag,
33 U64TypeTag,
34 U128TypeTag,
35 U256TypeTag,
36};
37pub use self::vector::VecTypeTag;
38
39pub trait MoveType {
45 type TypeTag: MoveTypeTag;
46}
47
48pub trait MoveTypeTag {
50 fn to_type_tag(&self) -> TypeTag;
51
52 fn from_type_tag(value: &TypeTag) -> Result<Self, TypeTagError>
53 where
54 Self: Sized;
55}
56
57impl<T> MoveTypeTag for T
58where
59 T: MoveDatatypeTag,
60{
61 fn from_type_tag(value: &TypeTag) -> Result<Self, TypeTagError>
62 where
63 Self: Sized,
64 {
65 match value {
66 TypeTag::Struct(stag) => Ok(Self::from_struct_tag(stag)?),
67 other => Err(TypeTagError::Variant {
68 expected: "Struct(_)".to_owned(),
69 got: type_tag_variant_name(other),
70 }),
71 }
72 }
73
74 fn to_type_tag(&self) -> TypeTag {
75 TypeTag::Struct(Box::new(self.to_struct_tag()))
76 }
77}
78
79pub trait MoveDatatype: MoveType<TypeTag = Self::StructTag> {
85 type StructTag: MoveDatatypeTag;
86}
87
88pub trait MoveDatatypeTag: MoveTypeTag {
91 fn to_struct_tag(&self) -> StructTag;
92
93 fn from_struct_tag(value: &StructTag) -> Result<Self, StructTagError>
94 where
95 Self: Sized;
96}
97
98pub trait HasKey {
104 fn address(&self) -> Address;
106}
107
108pub trait ConstAddress {
114 const ADDRESS: Address;
115}
116
117pub trait ConstModule {
119 const MODULE: &IdentStr;
120}
121
122pub trait ConstName {
124 const NAME: &IdentStr;
125}
126
127pub trait ConstTypeTag: MoveType {
129 const TYPE_TAG: Self::TypeTag;
130}
131
132impl<T> ConstTypeTag for T
133where
134 T: ConstStructTag,
135{
136 const TYPE_TAG: Self::TypeTag = Self::STRUCT_TAG;
137}
138
139pub trait ConstStructTag: MoveDatatype {
141 const STRUCT_TAG: Self::StructTag;
142}
143
144#[derive(thiserror::Error, Debug)]
149pub enum TypeTagError {
150 #[error("Wrong TypeTag variant: expected {expected}, got {got}")]
151 Variant { expected: String, got: String },
152 #[error("StructTag params: {0}")]
153 StructTag(#[from] StructTagError),
154}
155
156#[derive(thiserror::Error, Debug)]
157pub enum StructTagError {
158 #[error("Wrong address: expected {expected}, got {got}")]
159 Address { expected: Address, got: Address },
160 #[error("Wrong module: expected {expected}, got {got}")]
161 Module {
162 expected: Identifier,
163 got: Identifier,
164 },
165 #[error("Wrong name: expected {expected}, got {got}")]
166 Name {
167 expected: Identifier,
168 got: Identifier,
169 },
170 #[error("Wrong type parameters: {0}")]
171 TypeParams(#[from] TypeParamsError),
172}
173
174#[derive(thiserror::Error, Debug)]
175pub enum TypeParamsError {
176 #[error("Wrong number of generics: expected {expected}, got {got}")]
177 Number { expected: usize, got: usize },
178 #[error("Wrong type for generic: {0}")]
179 TypeTag(Box<TypeTagError>),
180}
181
182impl From<TypeTagError> for TypeParamsError {
183 fn from(value: TypeTagError) -> Self {
184 Self::TypeTag(Box::new(value))
185 }
186}
187
188#[derive(thiserror::Error, Debug)]
193pub enum ParseTypeTagError {
194 #[error("Parsing TypeTag: {0}")]
195 FromStr(Box<dyn StdError + Send + Sync + 'static>),
196 #[error("Converting from TypeTag: {0}")]
197 TypeTag(#[from] TypeTagError),
198}
199
200impl ParseTypeTagError {
201 fn from_str(err: impl StdError + Send + Sync + 'static) -> Self {
202 Self::FromStr(err.into())
203 }
204}
205
206#[derive(thiserror::Error, Debug)]
207pub enum ParseStructTagError {
208 #[error("Parsing StructTag: {0}")]
209 FromStr(Box<dyn StdError + Send + Sync + 'static>),
210 #[error("Converting from StructTag: {0}")]
211 StructTag(#[from] StructTagError),
212}
213
214fn type_tag_variant_name(this: &TypeTag) -> String {
219 match this {
220 TypeTag::U8 => "U8",
221 TypeTag::U16 => "U16",
222 TypeTag::U32 => "U32",
223 TypeTag::U64 => "U64",
224 TypeTag::U128 => "U128",
225 TypeTag::U256 => "U256",
226 TypeTag::Bool => "Bool",
227 TypeTag::Address => "Address",
228 TypeTag::Signer => "Signer",
229 TypeTag::Vector(_) => "Vector",
230 TypeTag::Struct(_) => "Struct",
231 }
232 .to_owned()
233}