moq_lite/coding/
varint.rs1use std::convert::{TryFrom, TryInto};
6use std::fmt;
7
8use thiserror::Error;
9
10use super::{Decode, DecodeError, Encode};
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Error)]
13#[error("value out of range")]
14pub struct BoundsExceeded;
15
16#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
22pub struct VarInt(u64);
23
24impl VarInt {
25 pub const MAX: Self = Self((1 << 62) - 1);
27
28 pub const ZERO: Self = Self(0);
30
31 pub const fn from_u32(x: u32) -> Self {
34 Self(x as u64)
35 }
36
37 pub const fn from_u64(x: u64) -> Result<Self, BoundsExceeded> {
38 if x <= Self::MAX.0 {
39 Ok(Self(x))
40 } else {
41 Err(BoundsExceeded)
42 }
43 }
44
45 pub const fn into_inner(self) -> u64 {
47 self.0
48 }
49}
50
51impl From<VarInt> for u64 {
52 fn from(x: VarInt) -> Self {
53 x.0
54 }
55}
56
57impl From<VarInt> for usize {
58 fn from(x: VarInt) -> Self {
59 x.0 as usize
60 }
61}
62
63impl From<VarInt> for u128 {
64 fn from(x: VarInt) -> Self {
65 x.0 as u128
66 }
67}
68
69impl From<u8> for VarInt {
70 fn from(x: u8) -> Self {
71 Self(x.into())
72 }
73}
74
75impl From<u16> for VarInt {
76 fn from(x: u16) -> Self {
77 Self(x.into())
78 }
79}
80
81impl From<u32> for VarInt {
82 fn from(x: u32) -> Self {
83 Self(x.into())
84 }
85}
86
87impl TryFrom<u64> for VarInt {
88 type Error = BoundsExceeded;
89
90 fn try_from(x: u64) -> Result<Self, BoundsExceeded> {
92 let x = Self(x);
93 if x <= Self::MAX {
94 Ok(x)
95 } else {
96 Err(BoundsExceeded)
97 }
98 }
99}
100
101impl TryFrom<u128> for VarInt {
102 type Error = BoundsExceeded;
103
104 fn try_from(x: u128) -> Result<Self, BoundsExceeded> {
106 if x <= Self::MAX.into() {
107 Ok(Self(x as u64))
108 } else {
109 Err(BoundsExceeded)
110 }
111 }
112}
113
114impl TryFrom<usize> for VarInt {
115 type Error = BoundsExceeded;
116
117 fn try_from(x: usize) -> Result<Self, BoundsExceeded> {
119 Self::try_from(x as u64)
120 }
121}
122
123impl TryFrom<VarInt> for u32 {
124 type Error = BoundsExceeded;
125
126 fn try_from(x: VarInt) -> Result<Self, BoundsExceeded> {
128 if x.0 <= u32::MAX.into() {
129 Ok(x.0 as u32)
130 } else {
131 Err(BoundsExceeded)
132 }
133 }
134}
135
136impl TryFrom<VarInt> for u16 {
137 type Error = BoundsExceeded;
138
139 fn try_from(x: VarInt) -> Result<Self, BoundsExceeded> {
141 if x.0 <= u16::MAX.into() {
142 Ok(x.0 as u16)
143 } else {
144 Err(BoundsExceeded)
145 }
146 }
147}
148
149impl TryFrom<VarInt> for u8 {
150 type Error = BoundsExceeded;
151
152 fn try_from(x: VarInt) -> Result<Self, BoundsExceeded> {
154 if x.0 <= u8::MAX.into() {
155 Ok(x.0 as u8)
156 } else {
157 Err(BoundsExceeded)
158 }
159 }
160}
161
162impl fmt::Display for VarInt {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 self.0.fmt(f)
165 }
166}
167
168impl<V> Decode<V> for VarInt {
169 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
171 if !r.has_remaining() {
172 return Err(DecodeError::Short);
173 }
174
175 let b = r.get_u8();
176 let tag = b >> 6;
177
178 let mut buf = [0u8; 8];
179 buf[0] = b & 0b0011_1111;
180
181 let x = match tag {
182 0b00 => u64::from(buf[0]),
183 0b01 => {
184 if !r.has_remaining() {
185 return Err(DecodeError::Short);
186 }
187 r.copy_to_slice(buf[1..2].as_mut());
188 u64::from(u16::from_be_bytes(buf[..2].try_into().unwrap()))
189 }
190 0b10 => {
191 if r.remaining() < 3 {
192 return Err(DecodeError::Short);
193 }
194 r.copy_to_slice(buf[1..4].as_mut());
195 u64::from(u32::from_be_bytes(buf[..4].try_into().unwrap()))
196 }
197 0b11 => {
198 if r.remaining() < 7 {
199 return Err(DecodeError::Short);
200 }
201 r.copy_to_slice(buf[1..8].as_mut());
202 u64::from_be_bytes(buf)
203 }
204 _ => unreachable!(),
205 };
206
207 Ok(Self(x))
208 }
209}
210
211impl<V> Encode<V> for VarInt {
212 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) {
214 if self.0 < (1u64 << 6) {
215 w.put_u8(self.0 as u8);
216 } else if self.0 < (1u64 << 14) {
217 w.put_u16((0b01 << 14) | self.0 as u16);
218 } else if self.0 < (1u64 << 30) {
219 w.put_u32((0b10 << 30) | self.0 as u32);
220 } else {
221 w.put_u64((0b11 << 62) | self.0);
222 }
223 }
224}
225
226impl<V> Encode<V> for u64 {
227 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) {
229 let v = VarInt::try_from(*self).expect("u64 too large");
231 v.encode(w, version)
232 }
233}
234
235impl<V> Decode<V> for u64 {
236 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
237 VarInt::decode(r, version).map(|v| v.into_inner())
238 }
239}
240
241impl<V> Encode<V> for usize {
242 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) {
244 let v = VarInt::try_from(*self).expect("usize too large");
246 v.encode(w, version)
247 }
248}
249
250impl<V> Decode<V> for usize {
251 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
252 VarInt::decode(r, version).map(|v| v.into_inner() as usize)
253 }
254}
255
256impl<V> Encode<V> for u32 {
257 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) {
258 VarInt::from(*self).encode(w, version)
259 }
260}
261
262impl<V> Decode<V> for u32 {
263 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
264 let v = VarInt::decode(r, version)?;
265 let v = v.try_into().map_err(|_| DecodeError::BoundsExceeded)?;
266 Ok(v)
267 }
268}