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;
90 pub(crate) use serdes;
91}
92
93macro_rules! felt_newtypes {
101 ([$($felt:ident),* $(,)?]; [$($felt251:ident),* $(,)?]) => {
102 crate::macros::felt_newtypes!(@define_felt $($felt),*);
103 crate::macros::felt_newtypes!(@define_felt251 $($felt251),*);
104
105 pub mod macro_prelude {
106 pub use super::felt;
107 pub use super::felt_bytes;
108
109 crate::macros::felt_newtypes!(@generate_felt_macro $($felt),*);
110 crate::macros::felt_newtypes!(@generate_felt251_macro $($felt251),*);
111
112 crate::macros::felt_newtypes!(@generate_use $($felt),*);
113 crate::macros::felt_newtypes!(@generate_use $($felt251),*);
114 }
115 };
116
117 (@define_felt $head:ident, $($tail:ident),+ $(,)?) => {
118 crate::macros::felt_newtypes!(@define_felt $head);
119 crate::macros::felt_newtypes!(@define_felt $($tail),+);
120 };
121
122 (@define_felt $target:ident) => {
123 paste::paste! {
124 #[derive(Copy, Clone, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, PartialOrd, Ord, Dummy)]
125 pub struct $target(pub pathfinder_crypto::Felt);
126
127 #[allow(unused)]
128 impl $target {
129 pub const ZERO: Self = Self(pathfinder_crypto::Felt::ZERO);
130
131 pub fn as_inner(&self) -> &pathfinder_crypto::Felt {
132 &self.0
133 }
134 }
135
136 $crate::macros::fmt::thin_debug!($target);
137 $crate::macros::fmt::thin_display!($target);
138 }
139 };
140
141 (@define_felt251 $head:ident, $($tail:ident),+ $(,)?) => {
142 crate::macros::felt_newtypes!(@define_felt251 $head);
143 crate::macros::felt_newtypes!(@define_felt251 $($tail),+);
144 };
145
146 (@define_felt251 $target:ident) => {
147 paste::paste! {
148 #[derive(Copy, Clone, Default, PartialEq, Eq, Hash, serde::Serialize, PartialOrd, Ord, Dummy)]
149 pub struct $target(pub pathfinder_crypto::Felt);
150
151 $crate::macros::fmt::thin_debug!($target);
152 $crate::macros::fmt::thin_display!($target);
153
154 impl $target {
155 pub const ZERO: Self = Self(pathfinder_crypto::Felt::ZERO);
156
157 pub fn as_inner(&self) -> &pathfinder_crypto::Felt {
158 &self.0
159 }
160
161 pub const fn new(hash: Felt) -> Option<Self> {
162 if hash.has_more_than_251_bits() {
163 None
164 } else {
165 Some(Self(hash))
166 }
167 }
168
169 pub const fn new_or_panic(hash: Felt) -> Self {
170 match Self::new(hash) {
171 Some(key) => key,
172 None => panic!("Too many bits, need less for MPT keys"),
173 }
174 }
175
176 pub const fn get(&self) -> &Felt {
177 &self.0
178 }
179
180 pub fn view_bits(&self) -> &bitvec::slice::BitSlice<u8, bitvec::order::Msb0> {
181 self.0.view_bits()
182 }
183 }
184
185 impl<'de> serde::Deserialize<'de> for $target {
186 fn deserialize<D>(de: D) -> Result<Self, D::Error>
187 where
188 D: serde::Deserializer<'de>,
189 {
190 let felt = Felt::deserialize(de)?;
191 $target::new(felt).context("Felt251 overflow").map_err(serde::de::Error::custom)
192 }
193 }
194 }
195 };
196
197 (@generate_use $head:ident, $($tail:ident),+ $(,)?) => {
198 crate::macros::felt_newtypes!(@generate_use $head);
199 crate::macros::felt_newtypes!(@generate_use $($tail),+);
200 };
201
202 (@generate_use $target:ident) => {
203 paste::paste! {
204 pub use [<$target:snake>];
205 pub use [<$target:snake _bytes>];
206 }
207 };
208
209 (@generate_felt_macro $head:ident, $($tail:ident),+ $(,)?) => {
210 crate::macros::felt_newtypes!(@generate_felt_macro $head);
211 crate::macros::felt_newtypes!(@generate_felt_macro $($tail),+);
212 };
213
214 (@generate_felt_macro $target:ident) => {
215 paste::paste! {
216 #[macro_export]
217 macro_rules! [<$target:snake>] {
218 ($hex:expr) => {
219 $crate::$target($crate::felt!($hex))
220 };
221 }
222
223 #[macro_export]
224 macro_rules! [<$target:snake _bytes>] {
225 ($bytes:expr) => {
226 $crate::$target($crate::felt_bytes!($bytes))
227 };
228 }
229 }
230 };
231
232 (@generate_felt251_macro $head:ident, $($tail:ident),+ $(,)?) => {
233 crate::macros::felt_newtypes!(@generate_felt251_macro $head);
234 crate::macros::felt_newtypes!(@generate_felt251_macro $($tail),+);
235 };
236
237 (@generate_felt251_macro $target:ident) => {
238 paste::paste! {
239 #[macro_export]
240 macro_rules! [<$target:snake>] {
241 ($hex:expr) => {
242 $crate::$target::new_or_panic($crate::felt!($hex))
243 };
244 }
245
246 #[macro_export]
247 macro_rules! [<$target:snake _bytes>] {
248 ($bytes:expr) => {
249 $crate::$target::new_or_panic($crate::felt_bytes!($bytes))
250 };
251 }
252 }
253 };
254}
255pub(super) use felt_newtypes;
256
257pub(super) mod fmt {
258
259 macro_rules! thin_display {
261 ($target:ty) => {
262 impl std::fmt::Display for $target {
263 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264 std::fmt::Display::fmt(&self.0, f)
265 }
266 }
267 };
268 }
269
270 macro_rules! thin_debug {
277 ($target:ty) => {
278 impl std::fmt::Debug for $target {
279 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280 write!(fmt, "{}({})", stringify!($target), self.0)
281 }
282 }
283 };
284 }
285
286 pub(crate) use thin_debug;
287 pub(crate) use thin_display;
288}
289
290#[macro_export]
293macro_rules! felt {
294 ($hex:expr) => {{
295 use ::pathfinder_crypto;
298 const CONST_FELT: pathfinder_crypto::Felt =
299 match pathfinder_crypto::Felt::from_hex_str($hex) {
300 Ok(f) => f,
301 Err(pathfinder_crypto::HexParseError::InvalidNibble(_)) => {
302 panic!("Invalid hex digit")
303 }
304 Err(pathfinder_crypto::HexParseError::InvalidLength { .. }) => {
305 panic!("Too many hex digits")
306 }
307 Err(pathfinder_crypto::HexParseError::Overflow) => panic!("Felt overflow"),
308 };
309 CONST_FELT
310 }};
311}
312
313#[macro_export]
316macro_rules! felt_bytes {
317 ($bytes:expr) => {{
318 match pathfinder_crypto::Felt::from_be_slice($bytes) {
319 Ok(sh) => sh,
320 Err(pathfinder_crypto::OverflowError) => panic!("Invalid constant: OverflowError"),
321 }
322 }};
323}