pathfinder_common/
macros.rs1pub(super) mod i64_backed_u64 {
3
4 macro_rules! new_get_partialeq {
7 ($target:ty) => {
8 impl $target {
9 pub const fn new(val: u64) -> Option<Self> {
10 let max = i64::MAX as u64;
11 if val <= max {
13 Some(Self(val))
14 } else {
15 None
16 }
17 }
18
19 pub const fn new_or_panic(val: u64) -> Self {
20 match Self::new(val) {
21 Some(x) => x,
22 None => panic!("Invalid constant"),
23 }
24 }
25
26 pub const fn get(&self) -> u64 {
27 self.0
28 }
29 }
30
31 impl PartialEq<u64> for $target {
32 fn eq(&self, other: &u64) -> bool {
33 self.0 == *other
34 }
35 }
36
37 impl PartialEq<i64> for $target {
38 fn eq(&self, other: &i64) -> bool {
39 u64::try_from(*other).map(|x| self == &x).unwrap_or(false)
40 }
41 }
42
43 impl<T> fake::Dummy<T> for $target {
44 fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &T, rng: &mut R) -> Self {
45 Self(rng.gen_range(0..i64::MAX as u64))
46 }
47 }
48 };
49 }
50
51 macro_rules! serdes {
53 ($target:ty) => {
54 impl serde::Serialize for $target {
55 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
56 where
57 S: serde::Serializer,
58 {
59 serializer.serialize_u64(self.0)
60 }
61 }
62
63 impl<'de> serde::Deserialize<'de> for $target {
64 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
65 where
66 D: serde::Deserializer<'de>,
67 {
68 let raw = u64::deserialize(deserializer)?;
69 <$target>::deserialize_value::<D::Error>(raw)
70 }
71 }
72
73 impl $target {
74 pub fn deserialize_value<E>(raw: u64) -> Result<Self, E>
75 where
76 E: serde::de::Error,
77 {
78 <$target>::new(raw).ok_or_else(|| {
79 serde::de::Error::invalid_value(
80 serde::de::Unexpected::Unsigned(raw),
81 &"i64::MAX unsigned integer",
82 )
83 })
84 }
85 }
86 };
87 }
88
89 pub(crate) use {new_get_partialeq, serdes};
90}
91
92macro_rules! felt_newtypes {
100 ([$($felt:ident),* $(,)?]; [$($felt251:ident),* $(,)?]) => {
101 crate::macros::felt_newtypes!(@define_felt $($felt),*);
102 crate::macros::felt_newtypes!(@define_felt251 $($felt251),*);
103
104 pub mod macro_prelude {
105 pub use super::felt;
106 pub use super::felt_bytes;
107
108 crate::macros::felt_newtypes!(@generate_felt_macro $($felt),*);
109 crate::macros::felt_newtypes!(@generate_felt251_macro $($felt251),*);
110
111 crate::macros::felt_newtypes!(@generate_use $($felt),*);
112 crate::macros::felt_newtypes!(@generate_use $($felt251),*);
113 }
114 };
115
116 (@define_felt $head:ident, $($tail:ident),+ $(,)?) => {
117 crate::macros::felt_newtypes!(@define_felt $head);
118 crate::macros::felt_newtypes!(@define_felt $($tail),+);
119 };
120
121 (@define_felt $target:ident) => {
122 paste::paste! {
123 #[derive(Copy, Clone, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, PartialOrd, Ord, Dummy)]
124 pub struct $target(pub pathfinder_crypto::Felt);
125
126 #[allow(unused)]
127 impl $target {
128 pub const ZERO: Self = Self(pathfinder_crypto::Felt::ZERO);
129
130 pub fn as_inner(&self) -> &pathfinder_crypto::Felt {
131 &self.0
132 }
133 }
134
135 $crate::macros::fmt::thin_debug!($target);
136 $crate::macros::fmt::thin_display!($target);
137 }
138 };
139
140 (@define_felt251 $head:ident, $($tail:ident),+ $(,)?) => {
141 crate::macros::felt_newtypes!(@define_felt251 $head);
142 crate::macros::felt_newtypes!(@define_felt251 $($tail),+);
143 };
144
145 (@define_felt251 $target:ident) => {
146 paste::paste! {
147 #[derive(Copy, Clone, Default, PartialEq, Eq, Hash, serde::Serialize, PartialOrd, Ord, Dummy)]
148 pub struct $target(pub pathfinder_crypto::Felt);
149
150 $crate::macros::fmt::thin_debug!($target);
151 $crate::macros::fmt::thin_display!($target);
152
153 impl $target {
154 pub const ZERO: Self = Self(pathfinder_crypto::Felt::ZERO);
155
156 pub fn as_inner(&self) -> &pathfinder_crypto::Felt {
157 &self.0
158 }
159
160 pub const fn new(hash: Felt) -> Option<Self> {
161 if hash.has_more_than_251_bits() {
162 None
163 } else {
164 Some(Self(hash))
165 }
166 }
167
168 pub const fn new_or_panic(hash: Felt) -> Self {
169 match Self::new(hash) {
170 Some(key) => key,
171 None => panic!("Too many bits, need less for MPT keys"),
172 }
173 }
174
175 pub const fn get(&self) -> &Felt {
176 &self.0
177 }
178
179 pub fn view_bits(&self) -> &bitvec::slice::BitSlice<u8, bitvec::order::Msb0> {
180 self.0.view_bits()
181 }
182 }
183
184 impl<'de> serde::Deserialize<'de> for $target {
185 fn deserialize<D>(de: D) -> Result<Self, D::Error>
186 where
187 D: serde::Deserializer<'de>,
188 {
189 let felt = Felt::deserialize(de)?;
190 $target::new(felt).context("Felt251 overflow").map_err(serde::de::Error::custom)
191 }
192 }
193 }
194 };
195
196 (@generate_use $head:ident, $($tail:ident),+ $(,)?) => {
197 crate::macros::felt_newtypes!(@generate_use $head);
198 crate::macros::felt_newtypes!(@generate_use $($tail),+);
199 };
200
201 (@generate_use $target:ident) => {
202 paste::paste! {
203 pub use [<$target:snake>];
204 pub use [<$target:snake _bytes>];
205 }
206 };
207
208 (@generate_felt_macro $head:ident, $($tail:ident),+ $(,)?) => {
209 crate::macros::felt_newtypes!(@generate_felt_macro $head);
210 crate::macros::felt_newtypes!(@generate_felt_macro $($tail),+);
211 };
212
213 (@generate_felt_macro $target:ident) => {
214 paste::paste! {
215 #[macro_export]
216 macro_rules! [<$target:snake>] {
217 ($hex:expr) => {
218 $crate::$target($crate::felt!($hex))
219 };
220 }
221
222 #[macro_export]
223 macro_rules! [<$target:snake _bytes>] {
224 ($bytes:expr) => {
225 $crate::$target($crate::felt_bytes!($bytes))
226 };
227 }
228 }
229 };
230
231 (@generate_felt251_macro $head:ident, $($tail:ident),+ $(,)?) => {
232 crate::macros::felt_newtypes!(@generate_felt251_macro $head);
233 crate::macros::felt_newtypes!(@generate_felt251_macro $($tail),+);
234 };
235
236 (@generate_felt251_macro $target:ident) => {
237 paste::paste! {
238 #[macro_export]
239 macro_rules! [<$target:snake>] {
240 ($hex:expr) => {
241 $crate::$target::new_or_panic($crate::felt!($hex))
242 };
243 }
244
245 #[macro_export]
246 macro_rules! [<$target:snake _bytes>] {
247 ($bytes:expr) => {
248 $crate::$target::new_or_panic($crate::felt_bytes!($bytes))
249 };
250 }
251 }
252 };
253}
254pub(super) use felt_newtypes;
255
256pub(super) mod fmt {
257
258 macro_rules! thin_display {
260 ($target:ty) => {
261 impl std::fmt::Display for $target {
262 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
263 std::fmt::Display::fmt(&self.0, f)
264 }
265 }
266 };
267 }
268
269 macro_rules! thin_debug {
276 ($target:ty) => {
277 impl std::fmt::Debug for $target {
278 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
279 write!(fmt, "{}({})", stringify!($target), self.0)
280 }
281 }
282 };
283 }
284
285 pub(crate) use {thin_debug, thin_display};
286}
287
288#[macro_export]
291macro_rules! felt {
292 ($hex:expr) => {{
293 use ::pathfinder_crypto;
296 const CONST_FELT: pathfinder_crypto::Felt =
297 match pathfinder_crypto::Felt::from_hex_str($hex) {
298 Ok(f) => f,
299 Err(pathfinder_crypto::HexParseError::InvalidNibble(_)) => {
300 panic!("Invalid hex digit")
301 }
302 Err(pathfinder_crypto::HexParseError::InvalidLength { .. }) => {
303 panic!("Too many hex digits")
304 }
305 Err(pathfinder_crypto::HexParseError::Overflow) => panic!("Felt overflow"),
306 };
307 CONST_FELT
308 }};
309}
310
311#[macro_export]
314macro_rules! felt_bytes {
315 ($bytes:expr) => {{
316 match pathfinder_crypto::Felt::from_be_slice($bytes) {
317 Ok(sh) => sh,
318 Err(pathfinder_crypto::OverflowError) => panic!("Invalid constant: OverflowError"),
319 }
320 }};
321}