1use bytes::{Buf, BufMut};
2
3pub const MAX_VARINT: u64 = 4_611_686_018_427_387_903;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct VarInt(u64);
15
16#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
17pub enum VarIntError {
18 #[error("value {0} exceeds maximum varint value (2^62 - 1)")]
19 Overflow(u64),
20 #[error("insufficient bytes for varint decoding")]
21 UnexpectedEnd,
22}
23
24impl VarInt {
25 pub fn from_u64(v: u64) -> Result<Self, VarIntError> {
27 if v > MAX_VARINT {
28 Err(VarIntError::Overflow(v))
29 } else {
30 Ok(VarInt(v))
31 }
32 }
33
34 pub fn into_inner(self) -> u64 {
36 self.0
37 }
38
39 pub fn encoded_len(&self) -> usize {
41 if self.0 <= 63 {
42 1
43 } else if self.0 <= 16383 {
44 2
45 } else if self.0 <= 1073741823 {
46 4
47 } else {
48 8
49 }
50 }
51
52 pub fn encode(&self, buf: &mut impl BufMut) {
54 match self.encoded_len() {
55 1 => {
56 buf.put_u8(self.0 as u8);
57 }
58 2 => {
59 buf.put_u16((self.0 as u16) | 0x4000);
60 }
61 4 => {
62 buf.put_u32((self.0 as u32) | 0x80000000);
63 }
64 8 => {
65 buf.put_u64(self.0 | 0xC000000000000000);
66 }
67 _ => unreachable!(),
68 }
69 }
70
71 pub fn decode(buf: &mut impl Buf) -> Result<Self, VarIntError> {
73 if buf.remaining() < 1 {
74 return Err(VarIntError::UnexpectedEnd);
75 }
76 let first = buf.chunk()[0];
77 let prefix = first >> 6;
78 let len = 1usize << prefix;
79 if buf.remaining() < len {
80 return Err(VarIntError::UnexpectedEnd);
81 }
82 let val = match len {
83 1 => {
84 buf.advance(1);
85 (first & 0x3F) as u64
86 }
87 2 => {
88 let v = buf.get_u16();
89 (v & 0x3FFF) as u64
90 }
91 4 => {
92 let v = buf.get_u32();
93 (v & 0x3FFFFFFF) as u64
94 }
95 8 => {
96 let v = buf.get_u64();
97 v & 0x3FFFFFFFFFFFFFFF
98 }
99 _ => unreachable!(),
100 };
101 Ok(VarInt(val))
102 }
103}
104
105impl TryFrom<u64> for VarInt {
106 type Error = VarIntError;
107 fn try_from(v: u64) -> Result<Self, Self::Error> {
108 Self::from_u64(v)
109 }
110}
111
112impl From<VarInt> for u64 {
113 fn from(v: VarInt) -> u64 {
114 v.0
115 }
116}
117
118impl From<u32> for VarInt {
119 fn from(v: u32) -> Self {
120 VarInt(v as u64)
121 }
122}