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