1use super::{Deserialize, Error, Result, Serialize};
2
3#[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 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 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}