varint_rs/
lib.rs

1//! Varint is an alternative way of storing integer numbers.
2//! 
3//! Varints allow for the storage of larger integer types in a smaller amount of
4//! space. It does this by storing an integer using the `7` lower bits and a flag
5//! in the most-significant bit. This flag is set to `1` when more bytes should
6//! be read. The groups of `7` bits are then added from the least-significant
7//! group first.
8//! 
9//! ## Features
10//! - `signed` (default): allows for signed integers to be encoded and decoded
11//!   using [zigzag] encoding
12//! - `std` (default): implements the `VarintReader` and `VarintWriter` traits
13//!   respectively on:
14//!   - all [`std::io::Read`] implementors
15//!   - all [`std::io::Write`] implementors
16//! 
17//! Note: Disabling the `std` feature (which is enabled by default) allows for the
18//! crate to be used in a `#![no_std]` environment.
19//! 
20//! [`VarintReader`]: crate::VarintReader
21//! [`VarintWriter`]: crate::VarintWriter
22//! [`std::io::Read`]: std::io::Read
23//! [`std::io::Write`]: std::io::Write
24//! [zigzag]: https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding
25//! 
26//! ## Example
27//! ```
28//! // to allow the use of the `VarintWriter::write_*_varint` functions
29//! use varint_rs::VarintWriter;
30//! // to allow the use of the `VarintReader::read_*_varint` functions
31//! use varint_rs::VarintReader;
32//! 
33//! // an example to use for the buffer
34//! use std::io::Cursor;
35//! 
36//! // create an i32 set to `300`
37//! let number: i32 = 300;
38//! // create a buffer for the varint to be writen to
39//! // an i32 can be `4` bytes maximum, so we pre-allocate the capacity
40//! let mut buffer: Cursor<Vec<u8>> = Cursor::new(Vec::with_capacity(4));
41//! 
42//! // now we can write the varint into the buffer
43//! // `300` should only use `2` bytes instead of all `4`
44//! // the `write_*_varint` functions may return an `std::io::Error`
45//! buffer.write_i32_varint(number).unwrap();
46//! 
47//! // we reset the cursor pos back to `0`, this isn't varint stuff
48//! buffer.set_position(0);
49//! 
50//! // now we can read the varint from the buffer
51//! // we should read `300` which was the number we stored
52//! // the `read_*_varint` functions may return an `std::io::Error`
53//! let number: i32 = buffer.read_i32_varint().unwrap();
54//! ```
55//! 
56//! Note: This example assumes that the `default` features are in use.
57
58#![cfg_attr(not(feature = "std"), no_std)]
59
60#[cfg(feature = "signed")]
61pub mod zigzag;
62#[cfg(feature = "signed")]
63pub use zigzag::Zigzag;
64
65#[cfg(feature = "std")]
66use std::io;
67
68macro_rules! read_varint {
69  ($type: ty, $self: expr) => {
70    {
71      let mut shift: $type = 0;
72      let mut decoded: $type = 0;
73      let mut next: u8 = 0;
74
75      loop {
76        match VarintReader::read($self) {
77          Ok(value) => next = value,
78          Err(error) => Err(error)?
79        }
80
81        decoded |= ((next & 0b01111111) as $type) << shift;
82
83        if next & 0b10000000 == 0b10000000 {
84          shift += 7;
85        } else {
86          return Ok(decoded)
87        }
88      }
89    }
90  };
91}
92
93/// The `VarintReader` trait enables reading of varints.
94/// 
95/// This is pre-implemented on structures which implement [`std::io::Read`].
96/// 
97/// ## Example
98/// If you would like to implement `VarintReader` for a type, you'll have to
99/// specify a `VarintReader::Error` and create the `VarintReader::read` method.
100/// 
101/// As an example, this is how [`std::io::Read`] is implemented:
102/// ```rust,ignore
103/// use varint_rs::VarintReader;
104/// use std::io;
105/// 
106/// // we are implementing `VarintReader` for all `std::io::Read` implementors
107/// impl<R: io::Read> VarintReader for R {
108///   // reading can cause an error so we give it the appropriate error value
109///   type Error = io::Error;
110/// 
111///   // now we can implement the read function which will read the next u8 value
112///   // for the varint
113///   fn read(&mut self) -> Result<u8, Self::Error> {
114///     // i won't explain this as the implementation will be specific to the
115///     // type you're implementing on
116///     let mut buf: [u8; 1] = [0];
117/// 
118///     match io::Read::read(self, &mut buf) {
119///       Ok(count) => {
120///         if count == 1 {
121///           Ok(buf[0])
122///         } else {
123///           Err(io::Error::new(io::ErrorKind::UnexpectedEof, "could not read byte"))
124///         }
125///       },
126///       Err(error) => Err(error)
127///     }
128///   }
129/// }
130/// ```
131/// 
132/// [`std::io::Read`]: std::io::Read
133pub trait VarintReader {
134  type Error;
135  
136  /// Reads the next u8 for the varint.
137  fn read(&mut self) -> Result<u8, Self::Error>;
138
139  /// Reads an i8 from a signed 8-bit varint.
140  #[inline]
141  #[cfg(feature = "signed")]
142  fn read_i8_varint(&mut self) -> Result<i8, Self::Error> {
143    match self.read_u8_varint() {
144      Ok(value) => Ok(value.zigzag()),
145      Err(error) => Err(error)
146    }
147  }
148
149  /// Reads a u8 from an unsigned 8-bit varint.
150  fn read_u8_varint(&mut self) -> Result<u8, Self::Error> {
151    read_varint!(u8, self)
152  }
153
154  /// Reads an i16 from a signed 16-bit varint.
155  #[inline]
156  #[cfg(feature = "signed")]
157  fn read_i16_varint(&mut self) -> Result<i16, Self::Error> {
158    match self.read_u16_varint() {
159      Ok(value) => Ok(value.zigzag()),
160      Err(error) => Err(error)
161    }
162  }
163
164  /// Reads a u16 from an unsigned 16-bit varint.
165  fn read_u16_varint(&mut self) -> Result<u16, Self::Error> {
166    read_varint!(u16, self)
167  }
168
169  /// Reads an i32 from a signed 32-bit varint.
170  #[inline]
171  #[cfg(feature = "signed")]
172  fn read_i32_varint(&mut self) -> Result<i32, Self::Error> {
173    match self.read_u32_varint() {
174      Ok(value) => Ok(value.zigzag()),
175      Err(error) => Err(error)
176    }
177  }
178
179  /// Reads a u32 from an unsigned 32-bit varint.
180  fn read_u32_varint(&mut self) -> Result<u32, Self::Error> {
181    read_varint!(u32, self)
182  }
183
184  /// Reads an i64 from a signed 64-bit varint.
185  #[inline]
186  #[cfg(feature = "signed")]
187  fn read_i64_varint(&mut self) -> Result<i64, Self::Error> {
188    match self.read_u64_varint() {
189      Ok(value) => Ok(value.zigzag()),
190      Err(error) => Err(error)
191    }
192  }
193
194  /// Reads a u64 from an unsigned 64-bit varint.
195  fn read_u64_varint(&mut self) -> Result<u64, Self::Error> {
196    read_varint!(u64, self)
197  }
198
199  /// Reads an i128 from a signed 128-bit varint.
200  #[inline]
201  #[cfg(feature = "signed")]
202  fn read_i128_varint(&mut self) -> Result<i128, Self::Error> {
203    match self.read_u128_varint() {
204      Ok(value) => Ok(value.zigzag()),
205      Err(error) => Err(error)
206    }
207  }
208
209  /// Reads a u128 from an unsigned 128-bit varint.
210  fn read_u128_varint(&mut self) -> Result<u128, Self::Error> {
211    read_varint!(u128, self)
212  }
213
214  /// Reads an isize from a signed size-bit varint.
215  #[inline]
216  #[cfg(feature = "signed")]
217  fn read_isize_varint(&mut self) -> Result<isize, Self::Error> {
218    match self.read_usize_varint() {
219      Ok(value) => Ok(value.zigzag()),
220      Err(error) => Err(error)
221    }
222  }
223
224  /// Reads a usize from an unsigned size-bit varint.
225  fn read_usize_varint(&mut self) -> Result<usize, Self::Error> {
226    read_varint!(usize, self)
227  }
228}
229
230#[cfg(feature = "std")]
231impl<R: io::Read> VarintReader for R {
232  type Error = io::Error;
233
234  /// Reads the next u8 for the varint from a type which implements [`std::io::Read`].
235  /// 
236  /// [`std::io::Read`]: std::io::Read
237  fn read(&mut self) -> Result<u8, Self::Error> {
238    let mut buf: [u8; 1] = [0];
239
240    match io::Read::read(self, &mut buf) {
241      Ok(count) => {
242        if count == 1 {
243          Ok(buf[0])
244        } else {
245          Err(io::Error::new(io::ErrorKind::UnexpectedEof, "could not read byte"))
246        }
247      },
248      Err(error) => Err(error)
249    }
250  }
251}
252
253macro_rules! write_varint {
254  ($type: ty, $self: expr, $value: expr) => {
255    {
256      let mut value: $type = $value;
257
258      if value == 0 {
259        VarintWriter::write($self, 0)
260      } else {
261        while value >= 0b10000000 {
262          let next: u8 = ((value & 0b01111111) as u8) | 0b10000000;
263          value >>= 7;
264
265          match VarintWriter::write($self, next) {
266            Err(error) => Err(error)?,
267            Ok(_) => ()
268          }
269        }
270
271        VarintWriter::write($self, (value & 0b01111111) as u8)
272      }
273    }
274  };
275}
276
277/// The `VarintWriter` trait enable writing of varints.
278/// 
279/// This is pre-implemented on structures which implement [`std::io::Write`].
280/// 
281/// ## Example
282/// If you would like to implement `VarintWriter` for a type, you'll have to
283/// specify a `VarintWriter::Error` and create the `VarintWriter::write` method.
284/// 
285/// As an example, this is how [`std::io::Write`] is implemented:
286/// ```rust,ignore
287/// use varint_rs::VarintWriter;
288/// use std::io;
289/// 
290/// // we are implementing `VarintWriter` for all `std::io::Write` implementors
291/// impl<W: io::Write> VarintWriter for W {
292///   // writing can cause an error so we give it the appropriate error value
293///   type Error = io::Error;
294/// 
295///   // now we can implement the write function which will write the next u8 value(s)
296///   // of the varint
297///   fn write(&mut self, byte: u8) -> Result<(), Self::Error> {
298///     // i won't explain this as the implementation will be specific to the
299///     // type you're implementing on
300///     match io::Write::write_all(self, &[byte]) {
301///       Ok(_) => Ok(()),
302///       Err(error) => Err(error)
303///     }
304///   }
305/// }
306/// ```
307/// 
308/// [`std::io::Write`]: std::io::Write
309pub trait VarintWriter {
310  type Error;
311
312  /// Writes the next u8 for the varint.
313  fn write(&mut self, byte: u8) -> Result<(), Self::Error>;
314
315  /// Writes an i8 to a signed 8-bit varint.
316  #[inline]
317  #[cfg(feature = "signed")]
318  fn write_i8_varint(&mut self, value: i8) -> Result<(), Self::Error> {
319    self.write_u8_varint(value.zigzag())
320  }
321
322  /// Writes a u8 to an unsigned 8-bit varint.
323  fn write_u8_varint(&mut self, value: u8) -> Result<(), Self::Error> {
324    write_varint!(u8, self, value)
325  }
326
327  /// Writes an i16 to a signed 16-bit varint.
328  #[inline]
329  #[cfg(feature = "signed")]
330  fn write_i16_varint(&mut self, value: i16) -> Result<(), Self::Error> {
331    self.write_u16_varint(value.zigzag())
332  }
333
334  /// Writes a u16 to an unsigned 16-bit varint.
335  fn write_u16_varint(&mut self, value: u16) -> Result<(), Self::Error> {
336    write_varint!(u16, self, value)
337  }
338
339  /// Writes an i32 to a signed 32-bit varint.
340  #[inline]
341  #[cfg(feature = "signed")]
342  fn write_i32_varint(&mut self, value: i32) -> Result<(), Self::Error> {
343    self.write_u32_varint(value.zigzag())
344  }
345
346  /// Writes a u32 to an unsigned 32-bit varint.
347  fn write_u32_varint(&mut self, value: u32) -> Result<(), Self::Error> {
348    write_varint!(u32, self, value)
349  }
350
351  /// Writes an i64 to a signed 64-bit varint.
352  #[inline]
353  #[cfg(feature = "signed")]
354  fn write_i64_varint(&mut self, value: i64) -> Result<(), Self::Error> {
355    self.write_u64_varint(value.zigzag())
356  }
357
358  /// Writes a u64 to an unsigned 64-bit varint.
359  fn write_u64_varint(&mut self, value: u64) -> Result<(), Self::Error> {
360    write_varint!(u64, self, value)
361  }
362
363  /// Writes an i128 to a signed 128-bit varint.
364  #[inline]
365  #[cfg(feature = "signed")]
366  fn write_i128_varint(&mut self, value: i128) -> Result<(), Self::Error> {
367    self.write_u128_varint(value.zigzag())
368  }
369
370  /// Writes a u128 to an unsigned 128-bit varint.
371  fn write_u128_varint(&mut self, value: u128) -> Result<(), Self::Error> {
372    write_varint!(u128, self, value)
373  }
374
375  /// Writes an isize to a signed size-bit varint.
376  #[inline]
377  #[cfg(feature = "signed")]
378  fn write_isize_varint(&mut self, value: isize) -> Result<(), Self::Error> {
379    self.write_usize_varint(value.zigzag())
380  }
381
382  /// Writes a usize to an unsigned size-bit varint.
383  fn write_usize_varint(&mut self, value: usize) -> Result<(), Self::Error> {
384    write_varint!(usize, self, value)
385  }
386}
387
388#[cfg(feature = "std")]
389impl<W: io::Write> VarintWriter for W {
390  type Error = io::Error;
391
392  /// Writes the next u8 for the varint into a type which implements [`std::io::Write`].
393  /// 
394  /// [`std::io::Write`]: std::io::Write
395  #[inline]
396  fn write(&mut self, byte: u8) -> Result<(), Self::Error> {
397    match io::Write::write_all(self, &[byte]) {
398      Ok(_) => Ok(()),
399      Err(error) => Err(error)
400    }
401  }
402}