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