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