mirror of https://git.sr.ht/~stygianentity/bincode
Turned Config::INT_ENCODING back into a const, made a ton of varint_encode functions
This commit is contained in:
parent
7448b7bb87
commit
723bdd312a
10
docs/spec.md
10
docs/spec.md
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
Related issue: https://github.com/serde-rs/serde/issues/1756#issuecomment-689682123
|
Related issue: https://github.com/serde-rs/serde/issues/1756#issuecomment-689682123
|
||||||
|
|
||||||
|
## Endian
|
||||||
|
|
||||||
|
By default `bincode` will serialize values in little endian encoding. This can be overwritten in the `Config`.
|
||||||
|
|
||||||
## Basic types
|
## Basic types
|
||||||
|
|
||||||
Boolean types are encoded with 1 byte for each boolean type, with `0` being `false`, `1` being true. Whilst deserilizing every other value will throw an error.
|
Boolean types are encoded with 1 byte for each boolean type, with `0` being `false`, `1` being true. Whilst deserilizing every other value will throw an error.
|
||||||
|
|
@ -23,10 +27,10 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
```
|
```
|
||||||
|
|
||||||
## IntEncoding
|
## IntEncoding
|
||||||
Bincode currently supports 2 different types of `IntEncoding`:
|
Bincode currently supports 2 different types of `IntEncoding`. With the default config, `VarintEncoding` is selected.
|
||||||
|
|
||||||
### VarintEncoding
|
### VarintEncoding
|
||||||
Encoding an unsigned integer v (of any type excepting u8) works as follows:
|
Encoding an unsigned integer v (of any type excepting u8/i8) works as follows:
|
||||||
|
|
||||||
1. If `u < 251`, encode it as a single byte with that value.
|
1. If `u < 251`, encode it as a single byte with that value.
|
||||||
1. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
|
1. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
|
||||||
|
|
@ -34,6 +38,8 @@ Encoding an unsigned integer v (of any type excepting u8) works as follows:
|
||||||
1. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
|
1. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
|
||||||
1. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a u128 with value `u`.
|
1. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a u128 with value `u`.
|
||||||
|
|
||||||
|
`usize` is being encoded/decoded as a `u64` and `isize` is being encoded/decoded as a `i64`.
|
||||||
|
|
||||||
See the documentation of [VarintEncoding](https://docs.rs/bincode/latest/bincode/config/struct.VarintEncoding.html) for more information.
|
See the documentation of [VarintEncoding](https://docs.rs/bincode/latest/bincode/config/struct.VarintEncoding.html) for more information.
|
||||||
|
|
||||||
### FixintEncoding
|
### FixintEncoding
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,19 @@
|
||||||
use crate::int_encoding::FixintEncoding;
|
|
||||||
|
|
||||||
pub(crate) use self::internal::*;
|
pub(crate) use self::internal::*;
|
||||||
|
|
||||||
pub trait Config: InternalConfig + Sized {}
|
pub trait Config: InternalConfig + Sized {}
|
||||||
|
|
||||||
pub struct Default;
|
pub struct Default;
|
||||||
|
|
||||||
impl InternalConfig for Default {
|
impl InternalConfig for Default {}
|
||||||
type IntEncoding = FixintEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: InternalConfig> Config for T {}
|
impl<T: InternalConfig> Config for T {}
|
||||||
|
|
||||||
mod internal {
|
mod internal {
|
||||||
use crate::int_encoding::IntEncoding;
|
|
||||||
|
|
||||||
pub trait InternalConfig {
|
pub trait InternalConfig {
|
||||||
const ENDIAN: Endian = Endian::Little;
|
const ENDIAN: Endian = Endian::Little;
|
||||||
|
const INT_ENCODING: IntEncoding = IntEncoding::Variable;
|
||||||
const LIMIT: Option<u64> = None;
|
const LIMIT: Option<u64> = None;
|
||||||
const ALLOW_TRAILING: bool = true;
|
const ALLOW_TRAILING: bool = true;
|
||||||
|
|
||||||
type IntEncoding: IntEncoding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
|
|
@ -29,11 +22,16 @@ mod internal {
|
||||||
Big,
|
Big,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub enum IntEncoding {
|
||||||
|
Fixed,
|
||||||
|
Variable,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, C: InternalConfig> InternalConfig for &'a mut C {
|
impl<'a, C: InternalConfig> InternalConfig for &'a mut C {
|
||||||
const ENDIAN: Endian = C::ENDIAN;
|
const ENDIAN: Endian = C::ENDIAN;
|
||||||
|
const INT_ENCODING: IntEncoding = C::INT_ENCODING;
|
||||||
const LIMIT: Option<u64> = C::LIMIT;
|
const LIMIT: Option<u64> = C::LIMIT;
|
||||||
const ALLOW_TRAILING: bool = C::ALLOW_TRAILING;
|
const ALLOW_TRAILING: bool = C::ALLOW_TRAILING;
|
||||||
|
|
||||||
type IntEncoding = C::IntEncoding;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
use super::write::Writer;
|
use super::write::Writer;
|
||||||
use super::Encode;
|
use super::Encode;
|
||||||
use crate::{config::Config, error::Error, int_encoding::IntEncoding};
|
use crate::{
|
||||||
|
config::{Config, Endian, IntEncoding},
|
||||||
|
error::Error,
|
||||||
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
pub struct Encoder<W: Writer, C: Config> {
|
pub struct Encoder<W: Writer, C: Config> {
|
||||||
|
|
@ -27,23 +30,63 @@ impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_u16(&mut self, val: u16) -> Result<(), Error> {
|
fn encode_u16(&mut self, val: u16) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_u16(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_u16(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_u32(&mut self, val: u32) -> Result<(), Error> {
|
fn encode_u32(&mut self, val: u32) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_u32(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_u32(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_u64(&mut self, val: u64) -> Result<(), Error> {
|
fn encode_u64(&mut self, val: u64) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_u64(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_u64(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_u128(&mut self, val: u128) -> Result<(), Error> {
|
fn encode_u128(&mut self, val: u128) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_u128(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_u128(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_usize(&mut self, val: usize) -> Result<(), Error> {
|
fn encode_usize(&mut self, val: usize) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_usize(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_usize(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_i8(&mut self, val: i8) -> Result<(), Error> {
|
fn encode_i8(&mut self, val: i8) -> Result<(), Error> {
|
||||||
|
|
@ -51,31 +94,83 @@ impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_i16(&mut self, val: i16) -> Result<(), Error> {
|
fn encode_i16(&mut self, val: i16) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_i16(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_i16(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_i32(&mut self, val: i32) -> Result<(), Error> {
|
fn encode_i32(&mut self, val: i32) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_i32(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_i32(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_i64(&mut self, val: i64) -> Result<(), Error> {
|
fn encode_i64(&mut self, val: i64) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_i64(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_i64(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_i128(&mut self, val: i128) -> Result<(), Error> {
|
fn encode_i128(&mut self, val: i128) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_i128(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_i128(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_isize(&mut self, val: isize) -> Result<(), Error> {
|
fn encode_isize(&mut self, val: isize) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_isize(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => {
|
||||||
|
crate::varint_encoding::varint_encode_isize(&mut self.writer, C::ENDIAN, val)
|
||||||
|
}
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_f32(&mut self, val: f32) -> Result<(), Error> {
|
fn encode_f32(&mut self, val: f32) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_f32(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => unimplemented!(), // crate::int_encoding::varint_encode_f32(&mut self.writer, C::ENDIAN, val),
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_f64(&mut self, val: f64) -> Result<(), Error> {
|
fn encode_f64(&mut self, val: f64) -> Result<(), Error> {
|
||||||
<C::IntEncoding as IntEncoding>::int_encode_f64(&mut self.writer, C::ENDIAN, val)
|
match C::INT_ENCODING {
|
||||||
|
IntEncoding::Variable => unimplemented!(), // crate::int_encoding::varint_encode_f64(&mut self.writer, C::ENDIAN, val),
|
||||||
|
IntEncoding::Fixed => match C::ENDIAN {
|
||||||
|
Endian::Big => self.writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => self.writer.write(&val.to_le_bytes()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_slice(&mut self, val: &[u8]) -> Result<(), Error> {
|
fn encode_slice(&mut self, val: &[u8]) -> Result<(), Error> {
|
||||||
|
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
use crate::{config::Endian, enc::write::Writer, error::Error};
|
|
||||||
|
|
||||||
pub trait IntEncoding {
|
|
||||||
fn int_encode_u16<W: Writer>(writer: &mut W, endian: Endian, val: u16) -> Result<(), Error>;
|
|
||||||
fn int_encode_u32<W: Writer>(writer: &mut W, endian: Endian, val: u32) -> Result<(), Error>;
|
|
||||||
fn int_encode_u64<W: Writer>(writer: &mut W, endian: Endian, val: u64) -> Result<(), Error>;
|
|
||||||
fn int_encode_u128<W: Writer>(writer: &mut W, endian: Endian, val: u128) -> Result<(), Error>;
|
|
||||||
fn int_encode_usize<W: Writer>(writer: &mut W, endian: Endian, val: usize)
|
|
||||||
-> Result<(), Error>;
|
|
||||||
|
|
||||||
fn int_encode_i16<W: Writer>(writer: &mut W, endian: Endian, val: i16) -> Result<(), Error>;
|
|
||||||
fn int_encode_i32<W: Writer>(writer: &mut W, endian: Endian, val: i32) -> Result<(), Error>;
|
|
||||||
fn int_encode_i64<W: Writer>(writer: &mut W, endian: Endian, val: i64) -> Result<(), Error>;
|
|
||||||
fn int_encode_i128<W: Writer>(writer: &mut W, endian: Endian, val: i128) -> Result<(), Error>;
|
|
||||||
fn int_encode_isize<W: Writer>(writer: &mut W, endian: Endian, val: isize)
|
|
||||||
-> Result<(), Error>;
|
|
||||||
|
|
||||||
fn int_encode_f32<W: Writer>(writer: &mut W, endian: Endian, val: f32) -> Result<(), Error>;
|
|
||||||
fn int_encode_f64<W: Writer>(writer: &mut W, endian: Endian, val: f64) -> Result<(), Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct VarintEncoding;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct FixintEncoding;
|
|
||||||
|
|
||||||
impl IntEncoding for FixintEncoding {
|
|
||||||
fn int_encode_u16<W: Writer>(writer: &mut W, endian: Endian, val: u16) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_u32<W: Writer>(writer: &mut W, endian: Endian, val: u32) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_u64<W: Writer>(writer: &mut W, endian: Endian, val: u64) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_u128<W: Writer>(writer: &mut W, endian: Endian, val: u128) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_usize<W: Writer>(
|
|
||||||
writer: &mut W,
|
|
||||||
endian: Endian,
|
|
||||||
val: usize,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_i16<W: Writer>(writer: &mut W, endian: Endian, val: i16) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_i32<W: Writer>(writer: &mut W, endian: Endian, val: i32) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_i64<W: Writer>(writer: &mut W, endian: Endian, val: i64) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_i128<W: Writer>(writer: &mut W, endian: Endian, val: i128) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_isize<W: Writer>(
|
|
||||||
writer: &mut W,
|
|
||||||
endian: Endian,
|
|
||||||
val: isize,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_f32<W: Writer>(writer: &mut W, endian: Endian, val: f32) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_encode_f64<W: Writer>(writer: &mut W, endian: Endian, val: f64) -> Result<(), Error> {
|
|
||||||
match endian {
|
|
||||||
Endian::Big => writer.write(&val.to_be_bytes()),
|
|
||||||
Endian::Little => writer.write(&val.to_le_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub mod error;
|
||||||
|
|
||||||
pub use bincode_derive::{Decodable, Encodable};
|
pub use bincode_derive::{Decodable, Encodable};
|
||||||
|
|
||||||
pub(crate) mod int_encoding;
|
pub(crate) mod varint_encoding;
|
||||||
|
|
||||||
pub fn encode_into_slice<E: enc::Encodeable>(
|
pub fn encode_into_slice<E: enc::Encodeable>(
|
||||||
val: E,
|
val: E,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
mod signed;
|
||||||
|
mod unsigned;
|
||||||
|
|
||||||
|
pub use self::signed::{
|
||||||
|
varint_encode_i128, varint_encode_i16, varint_encode_i32, varint_encode_i64,
|
||||||
|
varint_encode_isize,
|
||||||
|
};
|
||||||
|
pub use self::unsigned::{
|
||||||
|
varint_encode_u128, varint_encode_u16, varint_encode_u32, varint_encode_u64,
|
||||||
|
varint_encode_usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(self) const SINGLE_BYTE_MAX: u8 = 250;
|
||||||
|
pub(self) const U16_BYTE: u8 = 251;
|
||||||
|
pub(self) const U32_BYTE: u8 = 252;
|
||||||
|
pub(self) const U64_BYTE: u8 = 253;
|
||||||
|
pub(self) const U128_BYTE: u8 = 254;
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
use super::{varint_encode_u128, varint_encode_u16, varint_encode_u32, varint_encode_u64};
|
||||||
|
use crate::{config::Endian, enc::write::Writer, error::Error};
|
||||||
|
|
||||||
|
pub fn varint_encode_i16<W: Writer>(writer: &mut W, endian: Endian, val: i16) -> Result<(), Error> {
|
||||||
|
varint_encode_u16(
|
||||||
|
writer,
|
||||||
|
endian,
|
||||||
|
if val < 0 {
|
||||||
|
// let's avoid the edge case of i16::min_value()
|
||||||
|
// !n is equal to `-n - 1`, so this is:
|
||||||
|
// !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
|
||||||
|
!(val as u16) * 2 + 1
|
||||||
|
} else {
|
||||||
|
(val as u16) * 2
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_i32<W: Writer>(writer: &mut W, endian: Endian, val: i32) -> Result<(), Error> {
|
||||||
|
varint_encode_u32(
|
||||||
|
writer,
|
||||||
|
endian,
|
||||||
|
if val < 0 {
|
||||||
|
// let's avoid the edge case of i32::min_value()
|
||||||
|
// !n is equal to `-n - 1`, so this is:
|
||||||
|
// !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
|
||||||
|
!(val as u32) * 2 + 1
|
||||||
|
} else {
|
||||||
|
(val as u32) * 2
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_i64<W: Writer>(writer: &mut W, endian: Endian, val: i64) -> Result<(), Error> {
|
||||||
|
varint_encode_u64(
|
||||||
|
writer,
|
||||||
|
endian,
|
||||||
|
if val < 0 {
|
||||||
|
// let's avoid the edge case of i64::min_value()
|
||||||
|
// !n is equal to `-n - 1`, so this is:
|
||||||
|
// !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
|
||||||
|
!(val as u64) * 2 + 1
|
||||||
|
} else {
|
||||||
|
(val as u64) * 2
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_i128<W: Writer>(
|
||||||
|
writer: &mut W,
|
||||||
|
endian: Endian,
|
||||||
|
val: i128,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
varint_encode_u128(
|
||||||
|
writer,
|
||||||
|
endian,
|
||||||
|
if val < 0 {
|
||||||
|
// let's avoid the edge case of i128::min_value()
|
||||||
|
// !n is equal to `-n - 1`, so this is:
|
||||||
|
// !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
|
||||||
|
!(val as u128) * 2 + 1
|
||||||
|
} else {
|
||||||
|
(val as u128) * 2
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_isize<W: Writer>(
|
||||||
|
writer: &mut W,
|
||||||
|
endian: Endian,
|
||||||
|
val: isize,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// isize is being encoded as a i64
|
||||||
|
varint_encode_i64(writer, endian, val as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_i16() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_i32() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_i64() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_i128() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,371 @@
|
||||||
|
use super::{SINGLE_BYTE_MAX, U128_BYTE, U16_BYTE, U32_BYTE, U64_BYTE};
|
||||||
|
use crate::{config::Endian, enc::write::Writer, error::Error};
|
||||||
|
|
||||||
|
pub fn varint_encode_u16<W: Writer>(writer: &mut W, endian: Endian, val: u16) -> Result<(), Error> {
|
||||||
|
if val <= SINGLE_BYTE_MAX as _ {
|
||||||
|
writer.write(&[val as u8])
|
||||||
|
} else {
|
||||||
|
writer.write(&[U16_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&val.to_le_bytes()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_u32<W: Writer>(writer: &mut W, endian: Endian, val: u32) -> Result<(), Error> {
|
||||||
|
if val <= SINGLE_BYTE_MAX as _ {
|
||||||
|
writer.write(&[val as u8])
|
||||||
|
} else if val <= u16::MAX as _ {
|
||||||
|
writer.write(&[U16_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u16).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u16).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writer.write(&[U32_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&val.to_le_bytes()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_u64<W: Writer>(writer: &mut W, endian: Endian, val: u64) -> Result<(), Error> {
|
||||||
|
if val <= SINGLE_BYTE_MAX as _ {
|
||||||
|
writer.write(&[val as u8])
|
||||||
|
} else if val <= u16::MAX as _ {
|
||||||
|
writer.write(&[U16_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u16).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u16).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else if val <= u32::MAX as _ {
|
||||||
|
writer.write(&[U32_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u32).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u32).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writer.write(&[U64_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&val.to_le_bytes()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_u128<W: Writer>(
|
||||||
|
writer: &mut W,
|
||||||
|
endian: Endian,
|
||||||
|
val: u128,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if val <= SINGLE_BYTE_MAX as _ {
|
||||||
|
writer.write(&[val as u8])
|
||||||
|
} else if val <= u16::MAX as _ {
|
||||||
|
writer.write(&[U16_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u16).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u16).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else if val <= u32::MAX as _ {
|
||||||
|
writer.write(&[U32_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u32).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u32).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else if val <= u64::MAX as _ {
|
||||||
|
writer.write(&[U64_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&(val as u64).to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&(val as u64).to_le_bytes()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writer.write(&[U128_BYTE])?;
|
||||||
|
match endian {
|
||||||
|
Endian::Big => writer.write(&val.to_be_bytes()),
|
||||||
|
Endian::Little => writer.write(&val.to_le_bytes()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn varint_encode_usize<W: Writer>(
|
||||||
|
writer: &mut W,
|
||||||
|
endian: Endian,
|
||||||
|
val: usize,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// usize is being encoded as a u64
|
||||||
|
varint_encode_u64(writer, endian, val as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_u16() {
|
||||||
|
use crate::enc::write::SliceWriter;
|
||||||
|
let mut buffer = [0u8; 20];
|
||||||
|
|
||||||
|
// these should all encode to a single byte
|
||||||
|
for i in 0u16..=SINGLE_BYTE_MAX as u16 {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u16(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u16, i);
|
||||||
|
|
||||||
|
// Assert endianness doesn't matter
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u16(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u16, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 3 bytes (leading byte + 2 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [
|
||||||
|
SINGLE_BYTE_MAX as u16 + 1,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
700,
|
||||||
|
888,
|
||||||
|
1234,
|
||||||
|
u16::MAX,
|
||||||
|
] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u16(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &i.to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u16(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &i.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_u32() {
|
||||||
|
use crate::enc::write::SliceWriter;
|
||||||
|
let mut buffer = [0u8; 20];
|
||||||
|
|
||||||
|
// these should all encode to a single byte
|
||||||
|
for i in 0u32..=SINGLE_BYTE_MAX as u32 {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u32, i);
|
||||||
|
|
||||||
|
// Assert endianness doesn't matter
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u32, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 3 bytes (leading byte + 2 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [
|
||||||
|
SINGLE_BYTE_MAX as u32 + 1,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
700,
|
||||||
|
888,
|
||||||
|
1234,
|
||||||
|
u16::MAX as u32,
|
||||||
|
] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 5 bytes (leading byte + 4 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u16::MAX as u32 + 1, 100_000, 1_000_000, u32::MAX] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &i.to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u32(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &i.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_u64() {
|
||||||
|
use crate::enc::write::SliceWriter;
|
||||||
|
let mut buffer = [0u8; 20];
|
||||||
|
|
||||||
|
// these should all encode to a single byte
|
||||||
|
for i in 0u64..=SINGLE_BYTE_MAX as u64 {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u64, i);
|
||||||
|
|
||||||
|
// Assert endianness doesn't matter
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u64, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 3 bytes (leading byte + 2 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [
|
||||||
|
SINGLE_BYTE_MAX as u64 + 1,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
700,
|
||||||
|
888,
|
||||||
|
1234,
|
||||||
|
u16::MAX as u64,
|
||||||
|
] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 5 bytes (leading byte + 4 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u16::MAX as u64 + 1, 100_000, 1_000_000, u32::MAX as u64] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &(i as u32).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &(i as u32).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u32::MAX as u64 + 1, 500_0000_000, u64::MAX] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
assert_eq!(buffer[0], U64_BYTE);
|
||||||
|
assert_eq!(&buffer[1..9], &i.to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u64(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
assert_eq!(buffer[0], U64_BYTE);
|
||||||
|
assert_eq!(&buffer[1..9], &i.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_u128() {
|
||||||
|
use crate::enc::write::SliceWriter;
|
||||||
|
let mut buffer = [0u8; 20];
|
||||||
|
|
||||||
|
// these should all encode to a single byte
|
||||||
|
for i in 0u128..=SINGLE_BYTE_MAX as u128 {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u128, i);
|
||||||
|
|
||||||
|
// Assert endianness doesn't matter
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 1);
|
||||||
|
assert_eq!(buffer[0] as u128, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 3 bytes (leading byte + 2 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [
|
||||||
|
SINGLE_BYTE_MAX as u128 + 1,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
700,
|
||||||
|
888,
|
||||||
|
1234,
|
||||||
|
u16::MAX as u128,
|
||||||
|
] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 3);
|
||||||
|
assert_eq!(buffer[0], U16_BYTE);
|
||||||
|
assert_eq!(&buffer[1..3], &(i as u16).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 5 bytes (leading byte + 4 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u16::MAX as u128 + 1, 100_000, 1_000_000, u32::MAX as u128] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &(i as u32).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 5);
|
||||||
|
assert_eq!(buffer[0], U32_BYTE);
|
||||||
|
assert_eq!(&buffer[1..5], &(i as u32).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u32::MAX as u128 + 1, 500_0000_000, u64::MAX as u128] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
assert_eq!(buffer[0], U64_BYTE);
|
||||||
|
assert_eq!(&buffer[1..9], &(i as u64).to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
assert_eq!(buffer[0], U64_BYTE);
|
||||||
|
assert_eq!(&buffer[1..9], &(i as u64).to_le_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these values should encode in 17 bytes (leading byte + 16 bytes)
|
||||||
|
// Values chosen at random, add new cases as needed
|
||||||
|
for i in [u64::MAX as u128 + 1, u128::MAX] {
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 17);
|
||||||
|
assert_eq!(buffer[0], U128_BYTE);
|
||||||
|
assert_eq!(&buffer[1..17], &i.to_be_bytes());
|
||||||
|
|
||||||
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
|
varint_encode_u128(&mut writer, Endian::Little, i).unwrap();
|
||||||
|
assert_eq!(writer.bytes_written(), 17);
|
||||||
|
assert_eq!(buffer[0], U128_BYTE);
|
||||||
|
assert_eq!(&buffer[1..17], &i.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,6 @@ fn test_encodable() {
|
||||||
};
|
};
|
||||||
let mut slice = [0u8; 1024];
|
let mut slice = [0u8; 1024];
|
||||||
let bytes_written = bincode::encode_into_slice(start, &mut slice).unwrap();
|
let bytes_written = bincode::encode_into_slice(start, &mut slice).unwrap();
|
||||||
assert_eq!(bytes_written, 9);
|
assert_eq!(bytes_written, 3);
|
||||||
assert_eq!(&slice[..bytes_written], &[5, 0, 0, 0, 10, 0, 0, 0, 20]);
|
assert_eq!(&slice[..bytes_written], &[10, 10, 20]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue