dlhn/format/
big_uint.rs

1use crate::de::Error;
2use num_bigint::BigUint;
3use num_traits::Zero;
4use serde::{
5    de::{self, SeqAccess, Unexpected, Visitor},
6    ser::SerializeSeq,
7    Deserializer, Serializer,
8};
9
10struct BigUintVisitor;
11
12impl<'de> Visitor<'de> for BigUintVisitor {
13    type Value = BigUint;
14
15    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
16        formatter.write_str("format error")
17    }
18
19    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
20    where
21        A: SeqAccess<'de>,
22    {
23        let v = seq
24            .next_element::<Vec<u8>>()?
25            .ok_or(de::Error::invalid_value(Unexpected::Seq, &Error::Read))?;
26        Ok(BigUint::from_bytes_le(v.as_slice()))
27    }
28}
29
30pub fn serialize<T: Serializer>(big_uint: &BigUint, serializer: T) -> Result<T::Ok, T::Error> {
31    let mut seq = serializer.serialize_seq(None)?;
32
33    if big_uint.is_zero() {
34        seq.serialize_element(&0u8)?;
35    } else {
36        seq.serialize_element(&big_uint.to_bytes_le())?;
37    }
38
39    seq.end()
40}
41
42pub fn deserialize<'de, T: Deserializer<'de>>(deserializer: T) -> Result<BigUint, T::Error> {
43    deserializer.deserialize_tuple(1, BigUintVisitor)
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::{de::Deserializer, ser::Serializer};
49    use num_bigint::BigUint;
50
51    #[test]
52    fn serilize() {
53        assert_eq!(encode_big_uint(BigUint::from(0u8)), [0]);
54        assert_eq!(encode_big_uint(BigUint::from(u8::MAX)), [1, 255]);
55        assert_eq!(encode_big_uint(BigUint::from(u16::MAX)), [2, 255, 255]);
56        assert_eq!(encode_big_uint(BigUint::from(u16::MAX) + 1u8), [3, 0, 0, 1]);
57        assert_eq!(
58            encode_big_uint(BigUint::from(u32::MAX)),
59            [4, 255, 255, 255, 255]
60        );
61        assert_eq!(
62            encode_big_uint(BigUint::from(u32::MAX) + 1u8),
63            [5, 0, 0, 0, 0, 1]
64        );
65        assert_eq!(
66            encode_big_uint(BigUint::from(u64::MAX)),
67            [8, 255, 255, 255, 255, 255, 255, 255, 255]
68        );
69        assert_eq!(
70            encode_big_uint(BigUint::from(u64::MAX) + 1u8),
71            [9, 0, 0, 0, 0, 0, 0, 0, 0, 1]
72        );
73        assert_eq!(
74            encode_big_uint(BigUint::from(u128::MAX)),
75            [16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
76        );
77        assert_eq!(
78            encode_big_uint(BigUint::from(u128::MAX) + 1u8),
79            [17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
80        );
81    }
82
83    #[test]
84    fn deserialize() {
85        fn assert_big_uint(big_uint: BigUint) {
86            let buf = encode_big_uint(big_uint.clone());
87            let mut reader = buf.as_slice();
88            let mut deserializer = Deserializer::new(&mut reader);
89            assert_eq!(big_uint, super::deserialize(&mut deserializer).unwrap());
90        }
91
92        IntoIterator::into_iter([
93            BigUint::from(0u8),
94            BigUint::from(u8::MAX),
95            BigUint::from(u16::MAX),
96            BigUint::from(u16::MAX) + 1u8,
97            BigUint::from(u32::MAX),
98            BigUint::from(u32::MAX) + 1u8,
99            BigUint::from(u64::MAX),
100            BigUint::from(u64::MAX) + 1u8,
101            BigUint::from(u128::MAX),
102            BigUint::from(u128::MAX) + 1u8,
103        ])
104        .for_each(assert_big_uint);
105    }
106
107    fn encode_big_uint(big_uint: BigUint) -> Vec<u8> {
108        let mut buf = Vec::new();
109        let mut serializer = Serializer::new(&mut buf);
110        super::serialize(&big_uint, &mut serializer).unwrap();
111        buf
112    }
113}