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}