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