1use private::ConvertRuint;
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13
14pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
16where
17 T: ConvertRuint,
18 S: Serializer,
19{
20 value.into_ruint().serialize(serializer)
21}
22
23pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
25where
26 T: ConvertRuint,
27 D: Deserializer<'de>,
28{
29 T::Ruint::deserialize(deserializer).map(T::from_ruint)
30}
31
32pub mod opt {
36 use super::private::ConvertRuint;
37 use serde::{Deserialize, Deserializer, Serializer};
38
39 pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
41 where
42 T: ConvertRuint,
43 S: Serializer,
44 {
45 match value {
46 Some(value) => serializer.serialize_some(&value.into_ruint()),
47 None => serializer.serialize_none(),
48 }
49 }
50
51 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
53 where
54 T: ConvertRuint,
55 D: Deserializer<'de>,
56 {
57 Ok(Option::<T::Ruint>::deserialize(deserializer)?.map(T::from_ruint))
58 }
59}
60
61pub mod vec {
65 use super::private::ConvertRuint;
66 use alloc::vec::Vec;
67 use core::{fmt, marker::PhantomData};
68 use serde::{
69 de::{SeqAccess, Visitor},
70 ser::SerializeSeq,
71 Deserializer, Serializer,
72 };
73
74 pub fn serialize<T, S>(value: &[T], serializer: S) -> Result<S::Ok, S::Error>
76 where
77 T: ConvertRuint,
78 S: Serializer,
79 {
80 let mut seq = serializer.serialize_seq(Some(value.len()))?;
81 for val in value {
82 seq.serialize_element(&val.into_ruint())?;
83 }
84 seq.end()
85 }
86
87 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
89 where
90 T: ConvertRuint,
91 D: Deserializer<'de>,
92 {
93 struct VecVisitor<T> {
94 marker: PhantomData<T>,
95 }
96
97 impl<'de, T> Visitor<'de> for VecVisitor<T>
98 where
99 T: ConvertRuint,
100 {
101 type Value = Vec<T>;
102
103 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
104 formatter.write_str("a sequence")
105 }
106
107 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
108 where
109 A: SeqAccess<'de>,
110 {
111 let mut values = Vec::<T>::with_capacity(seq.size_hint().unwrap_or(0));
112
113 while let Some(value) = seq.next_element::<T::Ruint>()? {
114 values.push(T::from_ruint(value));
115 }
116 Ok(values)
117 }
118 }
119
120 let visitor = VecVisitor { marker: PhantomData };
121 deserializer.deserialize_seq(visitor)
122 }
123}
124
125pub mod u128_vec_vec_opt {
127 use alloy_primitives::U128;
128 use serde::{Deserialize, Deserializer, Serializer};
129
130 #[cfg(not(feature = "std"))]
131 use alloc::vec::Vec;
132
133 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u128>>>, D::Error>
136 where
137 D: Deserializer<'de>,
138 {
139 Option::<Vec<Vec<U128>>>::deserialize(deserializer)?.map_or_else(
140 || Ok(None),
141 |vec| {
142 Ok(Some(
143 vec.into_iter().map(|v| v.into_iter().map(|val| val.to()).collect()).collect(),
144 ))
145 },
146 )
147 }
148
149 pub fn serialize<S: Serializer>(
151 value: &Option<Vec<Vec<u128>>>,
152 s: S,
153 ) -> Result<S::Ok, S::Error> {
154 match value {
155 Some(vec) => {
156 let vec = vec
157 .iter()
158 .map(|v| v.iter().map(|val| U128::from(*val)).collect::<Vec<_>>())
159 .collect::<Vec<_>>();
160 s.serialize_some(&vec)
161 }
162 None => s.serialize_none(),
163 }
164 }
165}
166
167pub mod hashmap {
172 use super::private::ConvertRuint;
173 use alloy_primitives::map::HashMap;
174 use core::{fmt, hash::BuildHasher, marker::PhantomData};
175 use serde::{
176 de::MapAccess, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer,
177 };
178
179 pub fn serialize<K, V, S, H>(map: &HashMap<K, V, H>, serializer: S) -> Result<S::Ok, S::Error>
181 where
182 K: ConvertRuint,
183 V: Serialize,
184 S: Serializer,
185 H: BuildHasher,
186 {
187 let mut map_ser = serializer.serialize_map(Some(map.len()))?;
188 for (key, value) in map {
189 map_ser.serialize_entry(&key.into_ruint(), value)?;
190 }
191 map_ser.end()
192 }
193
194 pub fn deserialize<'de, K, V, D, H>(deserializer: D) -> Result<HashMap<K, V, H>, D::Error>
196 where
197 K: ConvertRuint + Eq + core::hash::Hash,
198 V: Deserialize<'de>,
199 D: Deserializer<'de>,
200 H: BuildHasher + Default,
201 {
202 struct HashMapVisitor<K, V, H> {
203 marker: PhantomData<(K, V, H)>,
204 }
205
206 impl<'de, K, V, H> serde::de::Visitor<'de> for HashMapVisitor<K, V, H>
207 where
208 K: ConvertRuint + Eq + core::hash::Hash,
209 V: Deserialize<'de>,
210 H: BuildHasher + Default,
211 {
212 type Value = HashMap<K, V, H>;
213
214 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
215 formatter.write_str("a map with quantity hex-encoded keys")
216 }
217
218 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
219 where
220 A: MapAccess<'de>,
221 {
222 let mut values =
223 HashMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), H::default());
224
225 while let Some((key, value)) = map.next_entry::<K::Ruint, V>()? {
226 values.insert(K::from_ruint(key), value);
227 }
228 Ok(values)
229 }
230 }
231
232 let visitor = HashMapVisitor { marker: PhantomData };
233 deserializer.deserialize_map(visitor)
234 }
235}
236
237pub mod btreemap {
240 use super::private::ConvertRuint;
241 use alloc::collections::BTreeMap;
242 use core::{fmt, marker::PhantomData};
243 use serde::{
244 de::MapAccess, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer,
245 };
246
247 pub fn serialize<K, V, S>(value: &BTreeMap<K, V>, serializer: S) -> Result<S::Ok, S::Error>
249 where
250 K: ConvertRuint + Ord,
251 V: Serialize,
252 S: Serializer,
253 {
254 let mut map = serializer.serialize_map(Some(value.len()))?;
255 for (key, val) in value {
256 map.serialize_entry(&key.into_ruint(), val)?;
257 }
258 map.end()
259 }
260
261 pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
263 where
264 K: ConvertRuint + Ord,
265 V: Deserialize<'de>,
266 D: Deserializer<'de>,
267 {
268 struct BTreeMapVisitor<K, V> {
269 key_marker: PhantomData<K>,
270 value_marker: PhantomData<V>,
271 }
272
273 impl<'de, K, V> serde::de::Visitor<'de> for BTreeMapVisitor<K, V>
274 where
275 K: ConvertRuint + Ord,
276 V: Deserialize<'de>,
277 {
278 type Value = BTreeMap<K, V>;
279
280 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
281 formatter.write_str("a map with quantity hex-encoded keys")
282 }
283
284 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
285 where
286 M: MapAccess<'de>,
287 {
288 let mut values = BTreeMap::new();
289
290 while let Some((key, value)) = map.next_entry::<K::Ruint, V>()? {
291 values.insert(K::from_ruint(key), value);
292 }
293 Ok(values)
294 }
295 }
296
297 let visitor = BTreeMapVisitor { key_marker: PhantomData, value_marker: PhantomData };
298 deserializer.deserialize_map(visitor)
299 }
300}
301
302#[expect(unnameable_types)]
304mod private {
305 #[doc(hidden)]
306 pub trait ConvertRuint: Copy + Sized {
307 type Ruint: Copy
310 + serde::Serialize
311 + serde::de::DeserializeOwned
312 + TryFrom<Self>
313 + TryInto<Self>;
314
315 #[inline]
316 fn into_ruint(self) -> Self::Ruint {
317 self.try_into().ok().unwrap()
318 }
319
320 #[inline]
321 fn from_ruint(ruint: Self::Ruint) -> Self {
322 ruint.try_into().ok().unwrap()
323 }
324 }
325
326 macro_rules! impl_from_ruint {
327 ($($primitive:ty = $ruint:ty),* $(,)?) => {
328 $(
329 impl ConvertRuint for $primitive {
330 type Ruint = $ruint;
331 }
332 )*
333 };
334 }
335
336 impl_from_ruint! {
337 bool = alloy_primitives::ruint::aliases::U1,
338 u8 = alloy_primitives::U8,
339 u16 = alloy_primitives::U16,
340 u32 = alloy_primitives::U32,
341 u64 = alloy_primitives::U64,
342 u128 = alloy_primitives::U128,
343 }
344}
345
346#[cfg(test)]
347mod tests {
348 use alloc::{string::ToString, vec, vec::Vec};
349 use serde::{Deserialize, Serialize};
350
351 #[test]
352 fn test_hex_u64() {
353 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
354 struct Value {
355 #[serde(with = "super")]
356 inner: u64,
357 }
358
359 let val = Value { inner: 1000 };
360 let s = serde_json::to_string(&val).unwrap();
361 assert_eq!(s, "{\"inner\":\"0x3e8\"}");
362
363 let deserialized: Value = serde_json::from_str(&s).unwrap();
364 assert_eq!(val, deserialized);
365 }
366
367 #[test]
368 fn test_u128_via_ruint() {
369 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
370 struct Value {
371 #[serde(with = "super")]
372 inner: u128,
373 }
374
375 let val = Value { inner: 1000 };
376 let s = serde_json::to_string(&val).unwrap();
377 assert_eq!(s, "{\"inner\":\"0x3e8\"}");
378
379 let deserialized: Value = serde_json::from_str(&s).unwrap();
380 assert_eq!(val, deserialized);
381
382 let s = "{\"inner\":\"1000\"}".to_string();
383 let deserialized: Value = serde_json::from_str(&s).unwrap();
384
385 assert_eq!(val, deserialized);
386 }
387
388 #[test]
389 fn test_u128_opt_via_ruint() {
390 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
391 struct Value {
392 #[serde(with = "super::opt")]
393 inner: Option<u128>,
394 }
395
396 let val = Value { inner: Some(1000) };
397 let s = serde_json::to_string(&val).unwrap();
398 assert_eq!(s, "{\"inner\":\"0x3e8\"}");
399
400 let deserialized: Value = serde_json::from_str(&s).unwrap();
401 assert_eq!(val, deserialized);
402
403 let s = "{\"inner\":\"1000\"}".to_string();
404 let deserialized: Value = serde_json::from_str(&s).unwrap();
405
406 assert_eq!(val, deserialized);
407
408 let val = Value { inner: None };
409 let s = serde_json::to_string(&val).unwrap();
410 assert_eq!(s, "{\"inner\":null}");
411
412 let deserialized: Value = serde_json::from_str(&s).unwrap();
413 assert_eq!(val, deserialized);
414 }
415
416 #[test]
417 fn test_u128_vec_via_ruint() {
418 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
419 struct Value {
420 #[serde(with = "super::vec")]
421 inner: Vec<u128>,
422 }
423
424 let val = Value { inner: vec![1000, 2000] };
425 let s = serde_json::to_string(&val).unwrap();
426 assert_eq!(s, "{\"inner\":[\"0x3e8\",\"0x7d0\"]}");
427
428 let deserialized: Value = serde_json::from_str(&s).unwrap();
429 assert_eq!(val, deserialized);
430 }
431
432 #[test]
433 fn test_u128_vec_vec_opt_via_ruint() {
434 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
435 struct Value {
436 #[serde(with = "super::u128_vec_vec_opt")]
437 inner: Option<Vec<Vec<u128>>>,
438 }
439
440 let val = Value { inner: Some(vec![vec![1000, 2000], vec![3000, 4000]]) };
441 let s = serde_json::to_string(&val).unwrap();
442 assert_eq!(s, "{\"inner\":[[\"0x3e8\",\"0x7d0\"],[\"0xbb8\",\"0xfa0\"]]}");
443
444 let deserialized: Value = serde_json::from_str(&s).unwrap();
445 assert_eq!(val, deserialized);
446
447 let val = Value { inner: None };
448 let s = serde_json::to_string(&val).unwrap();
449 assert_eq!(s, "{\"inner\":null}");
450
451 let deserialized: Value = serde_json::from_str(&s).unwrap();
452 assert_eq!(val, deserialized);
453 }
454
455 #[test]
456 fn test_u128_hashmap_via_ruint() {
457 use alloy_primitives::map::HashMap;
458
459 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
460 struct Value {
461 #[serde(with = "super::hashmap")]
462 inner: HashMap<u128, u128>,
463 }
464
465 let mut inner_map = HashMap::default();
466 inner_map.insert(1000, 2000);
467 inner_map.insert(3000, 4000);
468
469 let val = Value { inner: inner_map.clone() };
470 let s = serde_json::to_string(&val).unwrap();
471
472 let deserialized: Value = serde_json::from_str(&s).unwrap();
474 assert_eq!(val.inner, deserialized.inner);
475 }
476
477 #[test]
478 fn test_u128_btreemap_via_ruint() {
479 use alloc::collections::BTreeMap;
480
481 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
482 struct Value {
483 #[serde(with = "super::btreemap")]
484 inner: BTreeMap<u128, u128>,
485 }
486
487 let mut inner_map = BTreeMap::new();
488 inner_map.insert(1000, 2000);
489 inner_map.insert(3000, 4000);
490
491 let val = Value { inner: inner_map };
492 let s = serde_json::to_string(&val).unwrap();
493 assert_eq!(s, "{\"inner\":{\"0x3e8\":2000,\"0xbb8\":4000}}");
494
495 let deserialized: Value = serde_json::from_str(&s).unwrap();
496 assert_eq!(val, deserialized);
497 }
498}