1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00

add varbincode

This commit is contained in:
Wez Furlong 2019-03-16 00:38:03 -07:00
parent 217ad94c80
commit 322f7c74e6
8 changed files with 989 additions and 0 deletions

View File

@ -30,6 +30,7 @@ boxfnonce = "0.1"
rayon = "1.0" rayon = "1.0"
promise = { path = "promise" } promise = { path = "promise" }
base91 = { path = "base91" } base91 = { path = "base91" }
varbincode = { path = "varbincode" }
varu64 = "0.6" varu64 = "0.6"
bincode = "1.1" bincode = "1.1"
lazy_static = "1.3" lazy_static = "1.3"

13
varbincode/Cargo.toml Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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]);
}