reweb3_num/
types.rs

1//! Type aliases for big signed and unsigned integers. Each is an alias for either a [`BUint`] or a [`BInt`].
2
3use crate::{BInt, BUint};
4
5macro_rules! int_type_doc {
6    ($bits: literal, $sign: literal) => {
7        concat!($bits, "-bit ", $sign, " integer type.")
8    };
9}
10
11macro_rules! int_types {
12    { $($bits: literal $u: ident $i: ident; ) *}  => {
13        $(
14            #[doc = int_type_doc!($bits, "unsigned")]
15            pub type $u = BUint::<{$bits / 64}>;
16
17            #[doc = int_type_doc!($bits, "signed")]
18            pub type $i = BInt::<{$bits / 64}>;
19        )*
20    };
21}
22
23macro_rules! call_types_macro {
24    ($name: ident) => {
25        $name! {
26            128 U128 I128;
27            256 U256 I256;
28            512 U512 I512;
29            1024 U1024 I1024;
30            2048 U2048 I2048;
31            4096 U4096 I4096;
32            8192 U8192 I8192;
33        }
34    };
35}
36
37call_types_macro!(int_types);
38
39impl U256 {
40    pub fn to_be_bytes(self) -> [u8; 32] {
41        let buf = self.to_radix_be(256);
42
43        let mut target = [0u8; 32];
44
45        target[(32 - buf.len())..].copy_from_slice(&buf);
46
47        target
48    }
49
50    pub fn from_be_bytes(buf: [u8; 32]) -> Self {
51        Self::from_radix_be(&buf, 256).unwrap()
52    }
53}
54
55impl I256 {
56    pub fn to_be_bytes(self) -> [u8; 32] {
57        let buf = self.to_radix_be(256);
58
59        let mut target = [0xffu8; 32];
60
61        target[(32 - buf.len())..].copy_from_slice(&buf);
62
63        target
64    }
65
66    pub fn from_be_bytes(buf: [u8; 32]) -> Self {
67        Self::from_radix_be(&buf, 256).unwrap()
68    }
69}
70
71#[cfg(feature = "serde")]
72pub mod reweb3_serde {
73
74    use super::*;
75
76    use serde::{de, Deserialize, Serialize};
77
78    impl Serialize for U256 {
79        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80        where
81            S: serde::Serializer,
82        {
83            if serializer.is_human_readable() {
84                serializer.serialize_str(format!("{:#x}", self).as_str())
85            } else {
86                let buf = self.to_be_bytes()[(self.leading_zeros() / 8) as usize..].to_vec();
87
88                serializer.serialize_newtype_struct("uint256", &buf)
89            }
90        }
91    }
92
93    impl<'a> Deserialize<'a> for U256 {
94        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95        where
96            D: serde::Deserializer<'a>,
97        {
98            if deserializer.is_human_readable() {
99                deserializer.deserialize_any(U256Visitor)
100            } else {
101                let buff = deserializer.deserialize_newtype_struct("uint256", BytesVisitor)?;
102
103                Self::from_radix_be(&buff, 256).ok_or(de::Error::custom("u256: Out of range"))
104            }
105        }
106    }
107
108    impl Serialize for I256 {
109        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110        where
111            S: serde::Serializer,
112        {
113            if serializer.is_human_readable() {
114                serializer.serialize_str(self.to_str_radix(16).as_str())
115            } else {
116                let buf = self.to_be_bytes()[(self.leading_ones() / 8 - 1) as usize..].to_vec();
117                serializer.serialize_newtype_struct("int256", &buf)
118            }
119        }
120    }
121
122    impl<'a> Deserialize<'a> for I256 {
123        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124        where
125            D: serde::Deserializer<'a>,
126        {
127            if deserializer.is_human_readable() {
128                deserializer.deserialize_any(I256Visitor)
129            } else {
130                let buff = deserializer.deserialize_newtype_struct("int256", BytesVisitor)?;
131
132                Self::from_radix_be(&buff, 256).ok_or(de::Error::custom("i256: Out of range"))
133            }
134        }
135    }
136
137    struct BytesVisitor;
138
139    impl<'de> de::Visitor<'de> for BytesVisitor {
140        type Value = Vec<u8>;
141
142        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
143            write!(formatter, "expect bytes/bytes<M>")
144        }
145
146        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
147        where
148            E: de::Error,
149        {
150            Ok(v)
151        }
152    }
153
154    struct U256Visitor;
155
156    impl<'de> de::Visitor<'de> for U256Visitor {
157        type Value = U256;
158        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
159            write!(formatter, "expect string/number")
160        }
161
162        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
163        where
164            E: de::Error,
165        {
166            if v.starts_with("0x") {
167                U256::from_str_radix(&v[2..], 16).map_err(de::Error::custom)
168            } else {
169                U256::from_str_radix(v, 10).map_err(de::Error::custom)
170            }
171        }
172
173        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
174        where
175            E: de::Error,
176        {
177            self.visit_u128(v as u128)
178        }
179
180        fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
181        where
182            E: de::Error,
183        {
184            Ok(U256::from(v))
185        }
186    }
187
188    struct I256Visitor;
189
190    impl<'de> de::Visitor<'de> for I256Visitor {
191        type Value = I256;
192        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
193            write!(formatter, "expect string/number")
194        }
195
196        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
197        where
198            E: de::Error,
199        {
200            if v.starts_with("0x") {
201                I256::from_str_radix(&v[2..], 16).map_err(de::Error::custom)
202            } else if v.starts_with("-0x") {
203                I256::from_str_radix(&v[3..], 16).map_err(de::Error::custom)
204            } else {
205                I256::from_str_radix(v, 10).map_err(de::Error::custom)
206            }
207        }
208
209        fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
210        where
211            E: de::Error,
212        {
213            self.visit_i128(v as i128)
214        }
215
216        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
217        where
218            E: de::Error,
219        {
220            self.visit_i128(v as i128)
221        }
222
223        fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
224        where
225            E: de::Error,
226        {
227            Ok(I256::from(v))
228        }
229    }
230}
231
232#[cfg(test)]
233mod tests {
234    use super::*;
235
236    macro_rules! assert_int_bits {
237        { $($bits: literal $u: ident $i: ident; ) *} => {
238            $(
239                assert_eq!($u::BITS, $bits);
240                assert_eq!($i::BITS, $bits);
241            )*
242        }
243    }
244
245    #[test]
246    fn test_int_bits() {
247        call_types_macro!(assert_int_bits);
248    }
249}