Skip to main content

acta_maker_sdk/types/
macros.rs

1#[macro_export]
2macro_rules! define_numeric_newtype {
3    ($name:ident, $inner:ty) => {
4        #[derive(
5            Debug,
6            Default,
7            Clone,
8            Copy,
9            PartialEq,
10            Eq,
11            PartialOrd,
12            Ord,
13            Hash,
14            Serialize,
15            Deserialize,
16            DeriveDisplay,
17            From,
18            Into,
19        )]
20        pub struct $name($inner);
21
22        impl $name {
23            #[must_use]
24            pub const fn new(value: $inner) -> Self {
25                Self(value)
26            }
27
28            #[must_use]
29            pub const fn value(self) -> $inner {
30                self.0
31            }
32        }
33    };
34}
35
36#[macro_export]
37macro_rules! define_string_newtype {
38    ($name:ident) => {
39        #[derive(
40            Debug,
41            Clone,
42            PartialEq,
43            Eq,
44            PartialOrd,
45            Ord,
46            Hash,
47            Serialize,
48            Deserialize,
49            DeriveDisplay,
50            From,
51        )]
52        pub struct $name(pub String);
53
54        impl $name {
55            #[must_use]
56            pub fn new(value: impl Into<String>) -> Self {
57                Self(value.into())
58            }
59
60            #[must_use]
61            pub fn as_str(&self) -> &str {
62                &self.0
63            }
64        }
65
66        impl From<&str> for $name {
67            fn from(value: &str) -> Self {
68                Self(value.to_string())
69            }
70        }
71
72        impl AsRef<str> for $name {
73            fn as_ref(&self) -> &str {
74                &self.0
75            }
76        }
77
78        impl std::ops::Deref for $name {
79            type Target = str;
80
81            fn deref(&self) -> &Self::Target {
82                &self.0
83            }
84        }
85    };
86}
87
88#[macro_export]
89macro_rules! define_bytes32_newtype {
90    ($name:ident) => {
91        #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
92        pub struct $name(pub [u8; 32]);
93
94        impl $name {
95            #[must_use]
96            pub const fn new(bytes: [u8; 32]) -> Self {
97                Self(bytes)
98            }
99
100            #[must_use]
101            pub fn from_hex(s: &str) -> Option<Self> {
102                let s = s.strip_prefix("0x").unwrap_or(s);
103                let bytes = hex::decode(s).ok()?;
104                if bytes.len() != 32 {
105                    return None;
106                }
107                let mut arr = [0u8; 32];
108                arr.copy_from_slice(&bytes);
109                Some(Self(arr))
110            }
111
112            #[must_use]
113            pub fn hex(&self) -> String {
114                hex::encode(self.0)
115            }
116
117            #[must_use]
118            pub const fn as_bytes(&self) -> &[u8; 32] {
119                &self.0
120            }
121        }
122
123        impl std::fmt::Display for $name {
124            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125                write!(f, "{}", self.hex())
126            }
127        }
128
129        impl std::fmt::Debug for $name {
130            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131                f.debug_tuple(stringify!($name)).field(&self.hex()).finish()
132            }
133        }
134
135        impl serde::Serialize for $name {
136            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137            where
138                S: serde::Serializer,
139            {
140                serializer.serialize_str(&self.hex())
141            }
142        }
143
144        impl<'de> serde::Deserialize<'de> for $name {
145            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
146            where
147                D: serde::Deserializer<'de>,
148            {
149                let s = String::deserialize(deserializer)?;
150                Self::from_hex(&s).ok_or_else(|| {
151                    serde::de::Error::custom(format!("invalid {} hex: {:?}", stringify!($name), s))
152                })
153            }
154        }
155    };
156}