derse/
varint64.rs

1use super::{Deserialize, Error, Result, Serialize};
2
3/// A struct representing a variable-length 64-bit integer.
4#[derive(Debug, Default, PartialEq, Eq)]
5pub struct VarInt64(pub u64);
6
7const B: u8 = 7;
8const M: u8 = (1 << B) - 1;
9
10impl Serialize for VarInt64 {
11    /// Serializes the `VarInt64` into the given `Serializer`.
12    ///
13    /// # Arguments
14    ///
15    /// * `serializer` - The `Serializer` to serialize the data into.
16    ///
17    /// # Returns
18    ///
19    /// A `Result` indicating success or failure.
20    fn serialize_to<S: crate::Serializer>(&self, serializer: &mut S) -> Result<()> {
21        let mut v = self.0;
22        serializer.prepend([(v as u8) & M])?;
23        v >>= B;
24
25        while v != 0 {
26            serializer.prepend([v as u8 | (1 << B)])?;
27            v >>= B;
28        }
29
30        Ok(())
31    }
32}
33
34impl<'a> Deserialize<'a> for VarInt64 {
35    /// Deserializes the `VarInt64` from the given `Deserializer`.
36    ///
37    /// # Arguments
38    ///
39    /// * `buf` - The `Deserializer` to deserialize the data from.
40    ///
41    /// # Returns
42    ///
43    /// A `Result` containing the deserialized `VarInt64` or an error.
44    fn deserialize_from<D: crate::Deserializer<'a>>(buf: &mut D) -> Result<Self>
45    where
46        Self: Sized,
47    {
48        let mut v = 0u64;
49        for _ in 0..10 {
50            let front = buf.pop(1)?;
51            let c = front[0];
52            v = (v << B) | (c & M) as u64;
53            if c & (1 << B) == 0 {
54                return Ok(Self(v));
55            }
56        }
57        Err(Error::VarintIsShort)
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use crate::*;
64
65    #[test]
66    fn test_varint64() {
67        for v in [u64::MIN, 1, 10, 127, 128, 255, 256, u64::MAX] {
68            let ser = VarInt64(v);
69            let bytes = ser.serialize::<DownwardBytes>().unwrap();
70            let der = VarInt64::deserialize(&bytes[..]).unwrap();
71            assert_eq!(ser, der);
72        }
73
74        assert!(VarInt64::deserialize(&[][..]).is_err());
75        assert!(VarInt64::deserialize(&[128u8; 11][..]).is_err());
76    }
77}