Skip to main content

spinifex_unsigned_varint/
uvarint.rs

1use std::fmt;
2use std::convert::TryInto;
3
4use thiserror::Error;
5
6/// Number of bits in a byte.
7///
8/// This type largely exists to avoid magic numbers littering the codebase.
9pub const BITS_PER_BYTE: usize = 8;
10
11/// Maximum number of bytes in a binary representation for a `UVarInt`.
12///
13/// See the multiformat specification for details.
14pub const MAX_UVARINT_NUM_BYTES: usize = 9;
15
16/// Represents an encoding failure.
17///
18/// Returned whenever a function performs encoding of a `UVarInt` type.
19#[derive(Error, Debug)]
20pub enum EncodeError {
21    OutOfRange
22}
23
24impl fmt::Display for EncodeError {
25    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26        match self {
27            EncodeError::OutOfRange => 
28                write!(f, "Value overflows maximum output size")?
29        };
30
31        Ok(())
32    }
33}
34
35/// Represents a decoding failure.
36///
37/// Returned whenever a function performs decoding of a `UVarInt` type.
38#[derive(Error, Debug)]
39pub enum DecodeError {
40    OutOfRange
41}
42
43impl fmt::Display for DecodeError {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        match self {
46            DecodeError::OutOfRange => 
47                write!(f, "Input size overflows native representation")?
48        };
49
50        Ok(())
51    }
52}
53
54/// Represents an unsigned variable integer type, compliant with the multiformat
55/// of the same name.
56///
57/// The struct simply contains the underlying native integer type representing
58/// the type.
59#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Default, Hash)]
60pub struct UVarInt {
61    num: u128
62}
63
64impl UVarInt {
65    /// Constructs a new `UVarInt` from a native unsigned integer type.
66    ///
67    /// # Examples #
68    /// ```rust
69    /// use spinifex_unsigned_varint::uvarint::UVarInt;
70    ///
71    /// fn main() {
72    ///     let some_uvarint: UVarInt = UVarInt::new(128);
73    ///     println!("{}", some_uvarint);
74    /// }
75    ///
76    /// ```
77    pub fn new(num: u128) -> Self {
78        UVarInt {
79            num: num
80        }
81    }
82
83    /// Encodes the `UVarInt` type into its binary representation (as a
84    /// `Vec<u8>`).
85    ///
86    /// # Examples #
87    /// ```rust
88    /// use spinifex_unsigned_varint::uvarint::{UVarInt, EncodeError};
89    ///
90    /// fn main() {
91    ///     let bytes: Vec<u8> = vec![128, 1];
92    ///     let some_uvarint: UVarInt = match UVarInt::from_bytes(bytes) {
93    ///         Ok(uv) => uv,
94    ///         Err(e) => {
95    ///             println!("{:?}", e);
96    ///             panic!();
97    ///         }
98    ///     };
99    /// 
100    ///     println!("Bytes decoded as {}", some_uvarint);
101    /// }
102    ///
103    /// ```
104    /// 
105    /// # Errors #
106    /// 
107    /// Returns `EncodeError::OutOfRange` if the stored value would overflow the
108    /// maximum number of bytes of an unsigned varint (`MAX_UVARINT_NUM_BYTES`).
109    pub fn to_bytes(&self) -> Result<Vec<u8>, EncodeError> {
110        let num_bytes: usize = (UVarInt::u128_log2(self.num) /
111            (BITS_PER_BYTE - 1)) + 1;
112        
113        /* bounds check the number of bytes produced */
114        if num_bytes > MAX_UVARINT_NUM_BYTES {
115            return Err(EncodeError::OutOfRange);
116        }
117
118        /* define the bytes structure we'll use to assemble binary layout */
119        let mut bytes: Vec<u8> = vec![0u8; num_bytes];
120
121        /* base case where number fits entirely into one byte */
122        if self.num <= std::i8::MAX as u128 {
123            bytes = vec![self.num.try_into().unwrap()];
124            return Ok(bytes);
125        }
126
127        /* encode byte-at-a-time */
128        let mut n: u128 = self.num;
129
130        for i in 0..num_bytes {
131            bytes[i] = (n | 0x80) as u8;
132            n >>= 7;
133
134            if i + 1 == num_bytes {
135                bytes[i] &= 0x7f;
136                break;
137            }
138        }
139
140        Ok(bytes)
141    }
142
143    /// Decodes a sequence of bytes (as a `Vec<u8>`) into a valid `UVarInt`.
144    ///
145    /// # Examples #
146    /// 
147    /// ```rust
148    /// use spinifex_unsigned_varint::uvarint::{UVarInt, EncodeError};
149    ///
150    /// fn main() {
151    ///     let some_uvarint: UVarInt = UVarInt::new(128);
152    ///     let bytes: Vec<u8> = match some_uvarint.to_bytes() {
153    ///         Ok(b) => b,
154    ///         Err(e) => {
155    ///             println!("{:?}", e);
156    ///             panic!();
157    ///         }
158    ///     };
159    /// 
160    ///     println!("UVarInt encoded to {:?}", bytes);
161    /// }
162    ///
163    /// ```
164    ///
165    /// # Errors #
166    /// 
167    /// Returns `DecodeError::OutOfRange` if the number of provided bytes
168    /// exceeds `MAX_UVARINT_NUM_BYTES`.
169    pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, DecodeError> {
170        if bytes.len() > MAX_UVARINT_NUM_BYTES { /* bounds check */
171            return Err(DecodeError::OutOfRange);
172        }
173
174        let mut num: u128 = 0;
175
176        let mut n: u128 = 0;
177        let mut k: u128;
178
179        for i in 0..bytes.len() {
180            k = (bytes[i] & 0x7f) as u128;
181            n |= k << (i * 7);
182
183            if (bytes[i] & 0x80) == 0 {
184                num = n;
185                break;
186            }
187        }
188
189        let varint: UVarInt = UVarInt::new(num);
190        Ok(varint)
191    }
192
193    /// Calculates the (floor of the) base 2 logarithm of a native 128-bit
194    /// unsigned integer.
195    fn u128_log2(n: u128) -> usize {
196        (std::mem::size_of::<u128>() * BITS_PER_BYTE) -
197            n.leading_zeros() as usize - 1
198    }
199}
200
201impl fmt::Display for UVarInt {
202    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203        write!(f, "uv{}", self.num)
204    }
205}
206
207impl fmt::UpperHex for UVarInt {
208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209        fmt::UpperHex::fmt(&self.num, f) /* delegate to u128's implementation */
210    }
211}
212
213impl fmt::LowerHex for UVarInt {
214    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215        fmt::LowerHex::fmt(&self.num, f) /* delegate to u128's implementation */
216    }
217}
218
219impl fmt::Octal for UVarInt {
220    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221        fmt::Octal::fmt(&self.num, f) /* delegate to u128's implementation */
222    }
223}
224
225impl fmt::Binary for UVarInt {
226    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227        fmt::Binary::fmt(&self.num, f) /* delegate to u128's implementation */
228    }
229}
230
231#[cfg(test)]
232mod tests {
233    use super::*;
234
235    #[test]
236    fn test_to_bytes_spec1() -> Result<(), EncodeError> {
237        let number: u128 = 1;
238        let actual_uvarint: UVarInt = UVarInt::new(number);
239        
240        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
241        let expected_bytes: Vec<u8> = vec![1];
242
243        assert_eq!(actual_bytes, expected_bytes);
244        Ok(())
245    }
246
247    #[test]
248    fn test_to_bytes_spec2() -> Result<(), EncodeError> {
249        let number: u128 = 127;
250        let actual_uvarint: UVarInt = UVarInt::new(number);
251        
252        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
253        let expected_bytes: Vec<u8> = vec![127];
254
255        assert_eq!(actual_bytes, expected_bytes);
256        Ok(())
257    }
258
259    #[test]
260    fn test_to_bytes_spec3() -> Result<(), EncodeError> {
261        let number: u128 = 128;
262        let actual_uvarint: UVarInt = UVarInt::new(number);
263        
264        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
265        let expected_bytes: Vec<u8> = vec![128, 1];
266
267        assert_eq!(actual_bytes, expected_bytes);
268        Ok(())
269    }
270
271    #[test]
272    fn test_to_bytes_spec4() -> Result<(), EncodeError> {
273        let number: u128 = 255;
274        let actual_uvarint: UVarInt = UVarInt::new(number);
275        
276        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
277        let expected_bytes: Vec<u8> = vec![255, 1];
278
279        assert_eq!(actual_bytes, expected_bytes);
280        Ok(())
281    }
282
283    #[test]
284    fn test_to_bytes_spec5() -> Result<(), EncodeError> {
285        let number: u128 = 300;
286        let actual_uvarint: UVarInt = UVarInt::new(number);
287        
288        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
289        let expected_bytes: Vec<u8> = vec![172, 2];
290
291        assert_eq!(actual_bytes, expected_bytes);
292        Ok(())
293    }
294
295    #[test]
296    fn test_to_bytes_spec6() -> Result<(), EncodeError> {
297        let number: u128 = 16384;
298        let actual_uvarint: UVarInt = UVarInt::new(number);
299        
300        let actual_bytes: Vec<u8> = actual_uvarint.to_bytes()?;
301        let expected_bytes: Vec<u8> = vec![128, 128, 1];
302
303        assert_eq!(actual_bytes, expected_bytes);
304        Ok(())
305    }
306
307    #[test]
308    fn test_from_bytes_spec1() -> Result<(), DecodeError> {
309        let number: u128 = 1;
310        let bytes: Vec<u8> = vec![1];
311
312        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
313        let expected_uvarint: UVarInt = UVarInt::new(number);
314
315        assert_eq!(actual_uvarint, expected_uvarint);
316        Ok(())
317    }
318    
319    #[test]
320    fn test_from_bytes_spec2() -> Result<(), DecodeError> {
321        let number: u128 = 127;
322        let bytes: Vec<u8> = vec![127];
323
324        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
325        let expected_uvarint: UVarInt = UVarInt::new(number);
326
327        assert_eq!(actual_uvarint, expected_uvarint);
328        Ok(())
329    }
330
331    #[test]
332    fn test_from_bytes_spec3() -> Result<(), DecodeError> {
333        let number: u128 = 128;
334        let bytes: Vec<u8> = vec![128, 1];
335
336        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
337        let expected_uvarint: UVarInt = UVarInt::new(number);
338
339        assert_eq!(actual_uvarint, expected_uvarint);
340        Ok(())
341    }
342
343    #[test]
344    fn test_from_bytes_spec4() -> Result<(), DecodeError> {
345        let number: u128 = 255;
346        let bytes: Vec<u8> = vec![255, 1];
347
348        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
349        let expected_uvarint: UVarInt = UVarInt::new(number);
350
351        assert_eq!(actual_uvarint, expected_uvarint);
352        Ok(())
353    }
354
355    #[test]
356    fn test_from_bytes_spec5() -> Result<(), DecodeError> {
357        let number: u128 = 300;
358        let bytes: Vec<u8> = vec![172, 2];
359
360        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
361        let expected_uvarint: UVarInt = UVarInt::new(number);
362
363        assert_eq!(actual_uvarint, expected_uvarint);
364        Ok(())
365    }
366
367    #[test]
368    fn test_from_bytes_spec6() -> Result<(), DecodeError> {
369        let number: u128 = 16384;
370        let bytes: Vec<u8> = vec![128, 128, 1];
371
372        let actual_uvarint: UVarInt = UVarInt::from_bytes(bytes)?;
373        let expected_uvarint: UVarInt = UVarInt::new(number);
374
375        assert_eq!(actual_uvarint, expected_uvarint);
376        Ok(())
377    }
378}
379