1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
//! Variable length signed and unsigned integer types. //! Types support up to 128-bit integers, both are encoded to 1-17 bytes. //! //! Encoding rules are based on [SQLite 4 Varuint type](https://!sqlite.org/src4/doc/trunk/www/varint.wiki) //! with modifications for support of 128-bit long integers. //! Signed integers are encoded using the [Protobuf ZigZag approach](https://!developers.google.com/protocol-buffers/docs/encoding#signed-integers) //! and reuses unsigned integer as a storage. //! //! Unlike the Protobuf encoding rules `Varint` needs the first byte only to find out the length of the //! whole value. Microbenchmarks say that it is a lot faster. //! //! ## How to use //! //! Add dependency to your Cargo.toml: //! //! ```cargo //! [dependencies] //! varuint = "0.6" //! ``` //! //! Add imports to your code: //! //! ```rust,no_run //! //! use varuint::{Varint, Serializable, Deserializable}; //! ``` //! //! Use it: //! //! ```rust,no_run //! use std::mem; //! use std::io::Cursor; //! //! use varuint::*; //! //! fn main() { //! let mut cursor = Cursor::new(vec![]); //! let _ = cursor.write_varint(1u8).unwrap(); //! let _ = cursor.write_varint(-300i16).unwrap(); //! let v = Varint(-56_782i128); //! let _ = v.serialize(&mut cursor).unwrap(); //! cursor.set_position(0); //! assert_eq!(1u8, ReadVarint::<u8>::read_varint(&mut cursor).unwrap()); //! assert_eq!(-300i16, ReadVarint::<i16>::read_varint(&mut cursor).unwrap()); //! assert_eq!(v, Varint::<i128>::deserialize(&mut cursor).unwrap()); //! } //! ``` //! //! ## Encoding rules //! //! Encoding rules for unsinged integer `Varint` are (assuming value is `V`): //! //! * If `V<=240` then output a single byte `A0` equal to `V`. //! * If `V<=2031` then output `A0` as `(V-240)/256 + 241` and `A1` as `(V-240)%256`. //! * If `V<=67567` then output `A0` as `248`, `A1` as `(V-2032)/256`, and `A2` as `(V-2032)%256`. //! * If `V<=16_777_215` then output `A0` as `249` and `A1` through `A3` as a little-endian 3-byte integer. //! * If `V<=4_294_967_295` then output `A0` as `250` and `A1..A4` as a little-endian 4-byte integer. //! * If `V<=1_099_511_627_775` then output `A0` as `251` and `A1..A5` as a little-endian 5-byte integer. //! * If `V<=281_474_976_710_655` then output `A0` as `252` and `A1..A6` as a little-endian 6-byte integer. //! * If `V<=72_057_594_037_927_935` then output `A0` as `253` and `A1..A7` as a little-endian 7-byte integer. //! * If `V<=9_223_372_036_854_775_807` then output `A0` as `254` and `A1..A8` as a little-endian 8-byte integer. //! * Otherwise output `A0` as `255` and `A1..A16` as a little-endian 16-byte integer. //! //! Signed integer `Varint` converted to the unsigned integer `Varint` in the first place and then encoded as an unsigned integer. //! Conversion method makes values closer to 0 to take less space. //! See [Protobuf docs](https://!developers.google.com/protocol-buffers/docs/encoding#signed-integers) //! for details. mod read_write; mod ser_deser; mod varint; pub use crate::read_write::{ReadVarint, VarintSizeHint, WriteVarint}; pub use crate::ser_deser::{Deserializable, Serializable}; pub use crate::varint::{Varint, VarintBaseType};