mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 13:52:55 +03:00
add varbincode
This commit is contained in:
parent
217ad94c80
commit
322f7c74e6
@ -30,6 +30,7 @@ boxfnonce = "0.1"
|
||||
rayon = "1.0"
|
||||
promise = { path = "promise" }
|
||||
base91 = { path = "base91" }
|
||||
varbincode = { path = "varbincode" }
|
||||
varu64 = "0.6"
|
||||
bincode = "1.1"
|
||||
lazy_static = "1.3"
|
||||
|
13
varbincode/Cargo.toml
Normal file
13
varbincode/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
authors = ["Wez Furlong <wez@wezfurlong.org>"]
|
||||
name = "varbincode"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.3"
|
||||
leb128 = "0.2"
|
||||
serde = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_derive = "~1.0"
|
9
varbincode/README.md
Normal file
9
varbincode/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# varbincode
|
||||
|
||||
varbincode is a binary serialization format that uses variable
|
||||
length encoding for integer values, which typically results in
|
||||
reduced size of the encoded data.
|
||||
|
||||
It is losely based on `bincode` which is offered under an MIT
|
||||
license (same as the wezterm crate from which `varbincode`
|
||||
originates) and is Copyright 2014 Ty Overby.
|
382
varbincode/src/de.rs
Normal file
382
varbincode/src/de.rs
Normal file
@ -0,0 +1,382 @@
|
||||
use crate::error::{Error, Result};
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use serde::de::IntoDeserializer;
|
||||
|
||||
pub struct Deserializer<'a> {
|
||||
reader: &'a mut std::io::Read,
|
||||
}
|
||||
|
||||
impl<'a> Deserializer<'a> {
|
||||
pub fn new(reader: &'a mut std::io::Read) -> Self {
|
||||
Self { reader }
|
||||
}
|
||||
|
||||
fn read_signed(&mut self) -> Result<i64> {
|
||||
leb128::read::signed(&mut self.reader).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn read_unsigned(&mut self) -> Result<u64> {
|
||||
leb128::read::unsigned(&mut self.reader).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn read_vec(&mut self) -> Result<Vec<u8>> {
|
||||
let len: usize = serde::Deserialize::deserialize(&mut *self)?;
|
||||
let mut result = vec![0u8; len];
|
||||
self.reader.read_exact(&mut result)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_string(&mut self) -> Result<String> {
|
||||
let vec = self.read_vec()?;
|
||||
String::from_utf8(vec).map_err(|e| Error::InvalidUtf8Encoding(e.utf8_error()).into())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_uint {
|
||||
($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
|
||||
#[inline]
|
||||
fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value = self.$reader_method()?;
|
||||
if value > <$ty>::max_value() as u64 {
|
||||
Err(Error::NumberOutOfRange)
|
||||
} else {
|
||||
visitor.$visitor_method(value as $ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_int {
|
||||
($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
|
||||
#[inline]
|
||||
fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value = self.$reader_method()?;
|
||||
if value < <$ty>::min_value() as i64 || value > <$ty>::max_value() as i64 {
|
||||
Err(Error::NumberOutOfRange)
|
||||
} else {
|
||||
visitor.$visitor_method(value as $ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! impl_float {
|
||||
($dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
|
||||
#[inline]
|
||||
fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value = self.reader.$reader_method::<LittleEndian>()?;
|
||||
visitor.$visitor_method(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b> serde::Deserializer<'de> for &'a mut Deserializer<'b> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_u8(self.reader.read_u8()?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_i8(self.reader.read_i8()?)
|
||||
}
|
||||
|
||||
impl_uint!(u16, deserialize_u16, visit_u16, read_unsigned);
|
||||
impl_uint!(u32, deserialize_u32, visit_u32, read_unsigned);
|
||||
impl_uint!(u64, deserialize_u64, visit_u64, read_unsigned);
|
||||
|
||||
impl_int!(i16, deserialize_i16, visit_i16, read_signed);
|
||||
impl_int!(i32, deserialize_i32, visit_i32, read_signed);
|
||||
impl_int!(i64, deserialize_i64, visit_i64, read_signed);
|
||||
|
||||
impl_float!(deserialize_f32, visit_f32, read_f32);
|
||||
impl_float!(deserialize_f64, visit_f64, read_f64);
|
||||
|
||||
#[inline]
|
||||
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(Error::DeserializeAnyNotSupported)
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value: u8 = serde::Deserialize::deserialize(self)?;
|
||||
match value {
|
||||
1 => visitor.visit_bool(true),
|
||||
0 => visitor.visit_bool(false),
|
||||
value => Err(Error::InvalidBoolEncoding(value).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value: u32 = serde::Deserialize::deserialize(self)?;
|
||||
match std::char::from_u32(value) {
|
||||
Some(c) => visitor.visit_char(c),
|
||||
None => Err(Error::InvalidCharEncoding(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_string(self.read_string()?)
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_string(self.read_string()?)
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_byte_buf(self.read_vec()?)
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_byte_buf(self.read_vec()?)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
_enum: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_seq(Access {
|
||||
deserializer: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let value: u8 = serde::de::Deserialize::deserialize(&mut *self)?;
|
||||
match value {
|
||||
0 => visitor.visit_none(),
|
||||
1 => visitor.visit_some(&mut *self),
|
||||
v => Err(Error::InvalidTagEncoding(v as usize).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let len = serde::Deserialize::deserialize(&mut *self)?;
|
||||
|
||||
self.deserialize_tuple(len, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let len = serde::Deserialize::deserialize(&mut *self)?;
|
||||
|
||||
visitor.visit_map(Access {
|
||||
deserializer: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(
|
||||
self,
|
||||
_name: &str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_tuple(fields.len(), visitor)
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(Error::DeserializeIdentifierNotSupported)
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_newtype_struct(self)
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
len: usize,
|
||||
visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_tuple(len, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(Error::DeserializeIgnoredAnyNotSupported)
|
||||
}
|
||||
|
||||
fn is_human_readable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct Access<'a, 'b> {
|
||||
deserializer: &'a mut Deserializer<'b>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b> serde::de::SeqAccess<'de> for Access<'a, 'b> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
|
||||
where
|
||||
T: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.len > 0 {
|
||||
self.len -= 1;
|
||||
let value = serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?;
|
||||
Ok(Some(value))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
Some(self.len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b> serde::de::MapAccess<'de> for Access<'a, 'b> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
|
||||
where
|
||||
K: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.len > 0 {
|
||||
self.len -= 1;
|
||||
let key = serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?;
|
||||
Ok(Some(key))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
let value = serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
Some(self.len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b> serde::de::EnumAccess<'de> for &'a mut Deserializer<'b> {
|
||||
type Error = Error;
|
||||
type Variant = Self;
|
||||
|
||||
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
let idx: u32 = serde::de::Deserialize::deserialize(&mut *self)?;
|
||||
let val: Result<_> = seed.deserialize(idx.into_deserializer());
|
||||
Ok((val?, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b> serde::de::VariantAccess<'de> for &'a mut Deserializer<'b> {
|
||||
type Error = Error;
|
||||
|
||||
fn unit_variant(self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
|
||||
where
|
||||
T: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
serde::de::DeserializeSeed::deserialize(seed, self)
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
serde::de::Deserializer::deserialize_tuple(self, len, visitor)
|
||||
}
|
||||
|
||||
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor)
|
||||
}
|
||||
}
|
72
varbincode/src/error.rs
Normal file
72
varbincode/src/error.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use serde::{de, ser};
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
Message(String),
|
||||
Io(String),
|
||||
SequenceMustHaveLength,
|
||||
LebOverflow,
|
||||
DeserializeAnyNotSupported,
|
||||
DeserializeIdentifierNotSupported,
|
||||
DeserializeIgnoredAnyNotSupported,
|
||||
InvalidBoolEncoding(u8),
|
||||
InvalidCharEncoding(u32),
|
||||
InvalidUtf8Encoding(std::str::Utf8Error),
|
||||
InvalidTagEncoding(usize),
|
||||
NumberOutOfRange,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
impl ser::Error for Error {
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error::Message(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Error for Error {
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error::Message(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Error {
|
||||
Error::Io(format!("{}", err))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<leb128::read::Error> for Error {
|
||||
fn from(err: leb128::read::Error) -> Error {
|
||||
match err {
|
||||
leb128::read::Error::IoError(err) => Error::Io(format!("{}", err)),
|
||||
leb128::read::Error::Overflow => Error::LebOverflow,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Message(ref msg) => msg,
|
||||
Error::Io(ref msg) => msg,
|
||||
Error::SequenceMustHaveLength => "SequenceMustHaveLength",
|
||||
Error::DeserializeAnyNotSupported => "DeserializeAnyNotSupported",
|
||||
Error::LebOverflow => "LEB128 Overflow",
|
||||
Error::InvalidBoolEncoding(_) => "Invalid Bool Encoding",
|
||||
Error::InvalidCharEncoding(_) => "Invalid char encoding",
|
||||
Error::DeserializeIdentifierNotSupported => "DeserializeIdentifierNotSupported",
|
||||
Error::DeserializeIgnoredAnyNotSupported => "DeserializeIgnoredAnyNotSupported",
|
||||
Error::InvalidUtf8Encoding(_) => "InvalidUtf8Encoding",
|
||||
Error::InvalidTagEncoding(_) => "InvalidTagEncoding",
|
||||
Error::NumberOutOfRange => "NumberOutOfRange",
|
||||
}
|
||||
}
|
||||
}
|
26
varbincode/src/lib.rs
Normal file
26
varbincode/src/lib.rs
Normal file
@ -0,0 +1,26 @@
|
||||
//! varbincode is a binary serialization format that uses variable
|
||||
//! length encoding for integer values, which typically results in
|
||||
//! reduced size of the encoded data.
|
||||
pub mod de;
|
||||
pub mod error;
|
||||
pub mod ser;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
/// A convenience function for serializing a value as a byte vector
|
||||
/// See also `ser::Serializer`.
|
||||
pub fn serialize<T: serde::Serialize>(t: &T) -> Result<Vec<u8>, error::Error> {
|
||||
let mut result = Vec::new();
|
||||
let mut s = ser::Serializer::new(&mut result);
|
||||
t.serialize(&mut s)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// A convenience function for deserializing from a stream.
|
||||
/// See also `de::Deserializer`.
|
||||
pub fn deserialize<T: serde::de::DeserializeOwned, R: std::io::Read>(
|
||||
mut r: R,
|
||||
) -> Result<T, error::Error> {
|
||||
let mut d = de::Deserializer::new(&mut r);
|
||||
serde::Deserialize::deserialize(&mut d)
|
||||
}
|
345
varbincode/src/ser.rs
Normal file
345
varbincode/src/ser.rs
Normal file
@ -0,0 +1,345 @@
|
||||
use crate::error::Error;
|
||||
use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use serde::ser;
|
||||
|
||||
pub struct Serializer<'a> {
|
||||
writer: &'a mut std::io::Write,
|
||||
}
|
||||
|
||||
impl<'a> Serializer<'a> {
|
||||
pub fn new(writer: &'a mut std::io::Write) -> Self {
|
||||
Self { writer }
|
||||
}
|
||||
|
||||
fn write_signed(&mut self, val: i64) -> Result<usize, std::io::Error> {
|
||||
leb128::write::signed(&mut self.writer, val)
|
||||
}
|
||||
|
||||
fn write_unsigned(&mut self, val: u64) -> Result<usize, std::io::Error> {
|
||||
leb128::write::unsigned(&mut self.writer, val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::Serializer for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
type SerializeSeq = Self;
|
||||
type SerializeTuple = Self;
|
||||
type SerializeTupleStruct = Self;
|
||||
type SerializeTupleVariant = Self;
|
||||
type SerializeMap = Self;
|
||||
type SerializeStruct = Self;
|
||||
type SerializeStructVariant = Self;
|
||||
|
||||
fn serialize_bool(self, v: bool) -> Result<(), Error> {
|
||||
self.write_unsigned(if v { 1 } else { 0 })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _: &'static str) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u8(self, v: u8) -> Result<(), Error> {
|
||||
self.writer.write_u8(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u16(self, v: u16) -> Result<(), Error> {
|
||||
self.write_unsigned(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u32(self, v: u32) -> Result<(), Error> {
|
||||
self.write_unsigned(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_u64(self, v: u64) -> Result<(), Error> {
|
||||
self.write_unsigned(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i8(self, v: i8) -> Result<(), Error> {
|
||||
self.writer.write_i8(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i16(self, v: i16) -> Result<(), Error> {
|
||||
self.write_signed(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i32(self, v: i32) -> Result<(), Error> {
|
||||
self.write_signed(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_i64(self, v: i64) -> Result<(), Error> {
|
||||
self.write_signed(v as _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_f32(self, v: f32) -> Result<(), Error> {
|
||||
self.writer.write_f32::<LittleEndian>(v)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_f64(self, v: f64) -> Result<(), Error> {
|
||||
self.writer.write_f64::<LittleEndian>(v)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<(), Error> {
|
||||
self.serialize_bytes(v.as_bytes())
|
||||
}
|
||||
|
||||
fn serialize_char(self, c: char) -> Result<(), Error> {
|
||||
self.serialize_u32(c as u32)
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<(), Error> {
|
||||
self.serialize_u64(v.len() as u64)?;
|
||||
self.writer.write_all(v)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<(), Error> {
|
||||
self.serialize_u8(0)
|
||||
}
|
||||
|
||||
fn serialize_some<T: serde::Serialize + ?Sized>(self, v: &T) -> Result<(), Error> {
|
||||
self.serialize_u8(1)?;
|
||||
v.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
|
||||
let len = len.ok_or(Error::SequenceMustHaveLength)?;
|
||||
self.serialize_u64(len as u64)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Error> {
|
||||
self.serialize_u32(variant_index)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Error> {
|
||||
let len = len.ok_or(Error::SequenceMustHaveLength)?;
|
||||
self.serialize_u64(len as u64)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Error> {
|
||||
self.serialize_u32(variant_index)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
variant_index: u32,
|
||||
_variant: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
self.serialize_u32(variant_index)?;
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
variant_index: u32,
|
||||
_variant: &'static str,
|
||||
) -> Result<(), Error> {
|
||||
self.serialize_u32(variant_index)
|
||||
}
|
||||
|
||||
fn is_human_readable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeSeq for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeTuple for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeTupleStruct for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeTupleVariant for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeMap for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_key<K: ?Sized>(&mut self, value: &K) -> Result<(), Error>
|
||||
where
|
||||
K: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_value<V: ?Sized>(&mut self, value: &V) -> Result<(), Error>
|
||||
where
|
||||
V: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeStruct for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ser::SerializeStructVariant for &'a mut Serializer<'b> {
|
||||
type Ok = ();
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
141
varbincode/src/test.rs
Normal file
141
varbincode/src/test.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use super::{deserialize, error::Error, serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_derive::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn same<'de, T: serde::de::DeserializeOwned + Serialize + std::fmt::Debug + PartialEq>(a: T) {
|
||||
let encoded = serialize(&a).unwrap();
|
||||
let decoded: T = deserialize(encoded.as_slice()).unwrap();
|
||||
assert_eq!(decoded, a);
|
||||
eprintln!("{:?} encoded as {:?}", a, encoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
same(0u8);
|
||||
same(1u8);
|
||||
same(1i8);
|
||||
same(0i8);
|
||||
same(0u16);
|
||||
same(255u16);
|
||||
same(0xffffu16);
|
||||
same(0x7fffi16);
|
||||
same(-0x7fffi16);
|
||||
same(0x00ff_ffffu32);
|
||||
same(0xffff_ffffu32);
|
||||
same(0x00ff_ffffu64);
|
||||
same(0xffff_ffffu64);
|
||||
same(0xffff_ffff_ffffu64);
|
||||
same(0xffff_ffff_ffff_ffffu64);
|
||||
same(0f32);
|
||||
same(10.5f32);
|
||||
same(10.5f64);
|
||||
same(-10.5f64);
|
||||
|
||||
same("".to_string());
|
||||
same("hello".to_string());
|
||||
|
||||
same((1u8,));
|
||||
same((1u8, 2, 3));
|
||||
same((1u8, "foo".to_string()));
|
||||
|
||||
same(true);
|
||||
same(false);
|
||||
|
||||
same(Some(true));
|
||||
same(None::<bool>);
|
||||
|
||||
same('c');
|
||||
same(b'c');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_structs() {
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct Struct {
|
||||
a: isize,
|
||||
b: String,
|
||||
c: bool,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct Outer {
|
||||
inner: Struct,
|
||||
b: bool,
|
||||
second: Struct,
|
||||
};
|
||||
|
||||
same(Struct {
|
||||
a: -42,
|
||||
b: "hello".to_string(),
|
||||
c: true,
|
||||
});
|
||||
|
||||
same(Outer {
|
||||
inner: Struct {
|
||||
a: 1,
|
||||
b: "bee".to_string(),
|
||||
c: false,
|
||||
},
|
||||
b: true,
|
||||
second: Struct {
|
||||
a: 2,
|
||||
b: "other".to_string(),
|
||||
c: true,
|
||||
},
|
||||
});
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct NewType(usize);
|
||||
same(NewType(123));
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct NewTypeTuple(usize, bool);
|
||||
same(NewTypeTuple(123, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
enum TestEnum {
|
||||
NoArg,
|
||||
OneArg(usize),
|
||||
Args(usize, usize),
|
||||
AnotherNoArg,
|
||||
StructLike { x: usize, y: f32 },
|
||||
}
|
||||
same(TestEnum::NoArg);
|
||||
same(TestEnum::OneArg(4));
|
||||
same(TestEnum::Args(4, 5));
|
||||
same(TestEnum::AnotherNoArg);
|
||||
same(TestEnum::StructLike { x: 4, y: 3.14159 });
|
||||
same(vec![
|
||||
TestEnum::NoArg,
|
||||
TestEnum::OneArg(5),
|
||||
TestEnum::AnotherNoArg,
|
||||
TestEnum::StructLike { x: 4, y: 1.4 },
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec() {
|
||||
let v: Vec<u8> = vec![];
|
||||
same(v);
|
||||
same(vec![1u64]);
|
||||
same(vec![1u64, 2, 3, 4, 5, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map() {
|
||||
let mut m = HashMap::new();
|
||||
m.insert(4u64, "foo".to_string());
|
||||
m.insert(0u64, "bar".to_string());
|
||||
same(m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixed_size_array() {
|
||||
same([24u32; 32]);
|
||||
same([1u64, 2, 3, 4, 5, 6, 7, 8]);
|
||||
same([0u8; 19]);
|
||||
}
|
Loading…
Reference in New Issue
Block a user