starknet_core/serde/
num_hex.rs

1pub mod u64 {
2    use alloc::{fmt::Formatter, format};
3
4    use serde::{de::Visitor, Deserializer, Serializer};
5
6    struct NumHexVisitor;
7
8    pub fn serialize<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
9    where
10        S: Serializer,
11    {
12        if serializer.is_human_readable() {
13            serializer.serialize_str(&format!("{value:#x}"))
14        } else {
15            serializer.serialize_u64(*value)
16        }
17    }
18
19    pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
20    where
21        D: Deserializer<'de>,
22    {
23        if deserializer.is_human_readable() {
24            deserializer.deserialize_str(NumHexVisitor)
25        } else {
26            deserializer.deserialize_u64(NumHexVisitor)
27        }
28    }
29
30    impl Visitor<'_> for NumHexVisitor {
31        type Value = u64;
32
33        fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result {
34            write!(formatter, "string, or an array of u8")
35        }
36
37        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
38        where
39            E: serde::de::Error,
40        {
41            u64::from_str_radix(v.trim_start_matches("0x"), 16)
42                .map_err(|err| serde::de::Error::custom(format!("invalid u64 hex string: {err}")))
43        }
44
45        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
46        where
47            E: serde::de::Error,
48        {
49            Ok(v)
50        }
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    use hex_literal::hex;
59    use serde::{Deserialize, Serialize};
60
61    #[derive(Serialize, Deserialize)]
62    struct TestStruct(#[serde(with = "u64")] pub u64);
63
64    #[test]
65    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
66    fn bin_ser() {
67        let r = bincode::serialize(&TestStruct(0x1234)).unwrap();
68        assert_eq!(r, hex!("3412000000000000"));
69    }
70
71    #[test]
72    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
73    fn bin_deser() {
74        let r = bincode::deserialize::<TestStruct>(&hex!("3412000000000000")).unwrap();
75        assert_eq!(r.0, 0x1234);
76    }
77}