dlhn 0.1.7

DLHN is a blazing fast and small data serialization format.
Documentation
use crate::de::Error;
use num_bigint::BigUint;
use num_traits::Zero;
use serde::{
    de::{self, SeqAccess, Unexpected, Visitor},
    ser::SerializeSeq,
    Deserializer, Serializer,
};

struct BigUintVisitor;

impl<'de> Visitor<'de> for BigUintVisitor {
    type Value = BigUint;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("format error")
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: SeqAccess<'de>,
    {
        let v = seq
            .next_element::<Vec<u8>>()?
            .ok_or(de::Error::invalid_value(Unexpected::Seq, &Error::Read))?;
        Ok(BigUint::from_bytes_le(v.as_slice()))
    }
}

pub fn serialize<T: Serializer>(big_uint: &BigUint, serializer: T) -> Result<T::Ok, T::Error> {
    let mut seq = serializer.serialize_seq(None)?;

    if big_uint.is_zero() {
        seq.serialize_element(&0u8)?;
    } else {
        seq.serialize_element(&big_uint.to_bytes_le())?;
    }

    seq.end()
}

pub fn deserialize<'de, T: Deserializer<'de>>(deserializer: T) -> Result<BigUint, T::Error> {
    deserializer.deserialize_tuple(1, BigUintVisitor)
}

#[cfg(test)]
mod tests {
    use crate::{de::Deserializer, ser::Serializer};
    use num_bigint::BigUint;

    #[test]
    fn serilize() {
        assert_eq!(encode_big_uint(BigUint::from(0u8)), [0]);
        assert_eq!(encode_big_uint(BigUint::from(u8::MAX)), [1, 255]);
        assert_eq!(encode_big_uint(BigUint::from(u16::MAX)), [2, 255, 255]);
        assert_eq!(encode_big_uint(BigUint::from(u16::MAX) + 1u8), [3, 0, 0, 1]);
        assert_eq!(
            encode_big_uint(BigUint::from(u32::MAX)),
            [4, 255, 255, 255, 255]
        );
        assert_eq!(
            encode_big_uint(BigUint::from(u32::MAX) + 1u8),
            [5, 0, 0, 0, 0, 1]
        );
        assert_eq!(
            encode_big_uint(BigUint::from(u64::MAX)),
            [8, 255, 255, 255, 255, 255, 255, 255, 255]
        );
        assert_eq!(
            encode_big_uint(BigUint::from(u64::MAX) + 1u8),
            [9, 0, 0, 0, 0, 0, 0, 0, 0, 1]
        );
        assert_eq!(
            encode_big_uint(BigUint::from(u128::MAX)),
            [16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
        );
        assert_eq!(
            encode_big_uint(BigUint::from(u128::MAX) + 1u8),
            [17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
        );
    }

    #[test]
    fn deserialize() {
        fn assert_big_uint(big_uint: BigUint) {
            let buf = encode_big_uint(big_uint.clone());
            let mut reader = buf.as_slice();
            let mut deserializer = Deserializer::new(&mut reader);
            assert_eq!(big_uint, super::deserialize(&mut deserializer).unwrap());
        }

        IntoIterator::into_iter([
            BigUint::from(0u8),
            BigUint::from(u8::MAX),
            BigUint::from(u16::MAX),
            BigUint::from(u16::MAX) + 1u8,
            BigUint::from(u32::MAX),
            BigUint::from(u32::MAX) + 1u8,
            BigUint::from(u64::MAX),
            BigUint::from(u64::MAX) + 1u8,
            BigUint::from(u128::MAX),
            BigUint::from(u128::MAX) + 1u8,
        ])
        .for_each(assert_big_uint);
    }

    fn encode_big_uint(big_uint: BigUint) -> Vec<u8> {
        let mut buf = Vec::new();
        let mut serializer = Serializer::new(&mut buf);
        super::serialize(&big_uint, &mut serializer).unwrap();
        buf
    }
}