mirror of https://git.sr.ht/~stygianentity/bincode
Get serde working
This commit is contained in:
parent
b206032ff1
commit
0d6b8a48b6
|
|
@ -13,5 +13,6 @@ description = "A binary serialization / deserialization strategy and implementat
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc-serialize = "0.3.*"
|
rustc-serialize = "0.3.*"
|
||||||
byteorder = "0.3.*"
|
byteorder = "0.3.*"
|
||||||
|
num = "*"
|
||||||
serde = "*"
|
serde = "*"
|
||||||
serde_macros = "*"
|
serde_macros = "*"
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate num;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
use rustc_serialize::{Encodable, Decodable};
|
use rustc_serialize::{Encodable, Decodable};
|
||||||
|
|
@ -40,6 +41,13 @@ pub use refbox::{RefBox, StrBox, SliceBox};
|
||||||
pub use writer::{EncoderWriter, EncodingResult, EncodingError};
|
pub use writer::{EncoderWriter, EncodingResult, EncodingError};
|
||||||
pub use reader::{DecoderReader, DecodingResult, DecodingError};
|
pub use reader::{DecoderReader, DecodingResult, DecodingError};
|
||||||
use writer::SizeChecker;
|
use writer::SizeChecker;
|
||||||
|
pub use reader_serde::{
|
||||||
|
Deserializer,
|
||||||
|
DeserializeResult,
|
||||||
|
DeserializeError,
|
||||||
|
from_reader,
|
||||||
|
from_slice,
|
||||||
|
};
|
||||||
pub use writer_serde::{
|
pub use writer_serde::{
|
||||||
Serializer,
|
Serializer,
|
||||||
SerializeResult,
|
SerializeResult,
|
||||||
|
|
@ -56,6 +64,7 @@ mod writer;
|
||||||
mod reader;
|
mod reader;
|
||||||
mod refbox;
|
mod refbox;
|
||||||
mod writer_serde;
|
mod writer_serde;
|
||||||
|
mod reader_serde;
|
||||||
|
|
||||||
/// A limit on the amount of bytes that can be read or written.
|
/// A limit on the amount of bytes that can be read or written.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,599 @@
|
||||||
|
use std::io;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::io::Error as IoError;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::convert::From;
|
||||||
|
|
||||||
|
use byteorder::Error as ByteOrderError;
|
||||||
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
|
use num;
|
||||||
|
use serde;
|
||||||
|
use serde::de::value::ValueDeserializer;
|
||||||
|
|
||||||
|
use super::SizeLimit;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||||
|
pub struct InvalidEncoding {
|
||||||
|
desc: &'static str,
|
||||||
|
detail: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InvalidEncoding {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
InvalidEncoding { detail: None, desc } =>
|
||||||
|
write!(fmt, "{}", desc),
|
||||||
|
InvalidEncoding { detail: Some(ref detail), desc } =>
|
||||||
|
write!(fmt, "{} ({})", desc, detail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error that can be produced during decoding.
|
||||||
|
///
|
||||||
|
/// If decoding from a Buffer, assume that the buffer has been left
|
||||||
|
/// in an invalid state.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DeserializeError {
|
||||||
|
/// If the error stems from the reader that is being used
|
||||||
|
/// during decoding, that error will be stored and returned here.
|
||||||
|
IoError(IoError),
|
||||||
|
/// If the bytes in the reader are not decodable because of an invalid
|
||||||
|
/// encoding, this error will be returned. This error is only possible
|
||||||
|
/// if a stream is corrupted. A stream produced from `encode` or `encode_into`
|
||||||
|
/// should **never** produce an InvalidEncoding error.
|
||||||
|
InvalidEncoding(InvalidEncoding),
|
||||||
|
/// If decoding a message takes more than the provided size limit, this
|
||||||
|
/// error is returned.
|
||||||
|
SizeLimit,
|
||||||
|
SyntaxError,
|
||||||
|
EndOfStreamError,
|
||||||
|
UnknownFieldError,
|
||||||
|
MissingFieldError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for DeserializeError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
DeserializeError::IoError(ref err) => Error::description(err),
|
||||||
|
DeserializeError::InvalidEncoding(ref ib) => ib.desc,
|
||||||
|
DeserializeError::SizeLimit => "the size limit for decoding has been reached",
|
||||||
|
DeserializeError::SyntaxError => "syntax error",
|
||||||
|
DeserializeError::EndOfStreamError => "Unexpected EOF while reading a multi-byte number",
|
||||||
|
DeserializeError::UnknownFieldError => "unknown field error",
|
||||||
|
DeserializeError::MissingFieldError => "missing field error",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cause(&self) -> Option<&Error> {
|
||||||
|
match *self {
|
||||||
|
DeserializeError::IoError(ref err) => err.cause(),
|
||||||
|
DeserializeError::InvalidEncoding(_) => None,
|
||||||
|
DeserializeError::SizeLimit => None,
|
||||||
|
DeserializeError::SyntaxError => None,
|
||||||
|
DeserializeError::EndOfStreamError => None,
|
||||||
|
DeserializeError::UnknownFieldError => None,
|
||||||
|
DeserializeError::MissingFieldError => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IoError> for DeserializeError {
|
||||||
|
fn from(err: IoError) -> DeserializeError {
|
||||||
|
DeserializeError::IoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ByteOrderError> for DeserializeError {
|
||||||
|
fn from(err: ByteOrderError) -> DeserializeError {
|
||||||
|
match err {
|
||||||
|
ByteOrderError::Io(ioe) => DeserializeError::IoError(ioe),
|
||||||
|
ByteOrderError::UnexpectedEOF => DeserializeError::EndOfStreamError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<serde::de::value::Error> for DeserializeError {
|
||||||
|
fn from(err: serde::de::value::Error) -> DeserializeError {
|
||||||
|
use serde::de::value::Error;
|
||||||
|
|
||||||
|
match err {
|
||||||
|
Error::SyntaxError => DeserializeError::SyntaxError,
|
||||||
|
Error::EndOfStreamError => {
|
||||||
|
DeserializeError::EndOfStreamError
|
||||||
|
}
|
||||||
|
Error::UnknownFieldError(_) => DeserializeError::UnknownFieldError,
|
||||||
|
Error::MissingFieldError(_) => DeserializeError::MissingFieldError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DeserializeError {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
DeserializeError::IoError(ref ioerr) =>
|
||||||
|
write!(fmt, "IoError: {}", ioerr),
|
||||||
|
DeserializeError::InvalidEncoding(ref ib) =>
|
||||||
|
write!(fmt, "InvalidEncoding: {}", ib),
|
||||||
|
DeserializeError::SizeLimit =>
|
||||||
|
write!(fmt, "SizeLimit"),
|
||||||
|
DeserializeError::SyntaxError =>
|
||||||
|
write!(fmt, "SyntaxError"),
|
||||||
|
DeserializeError::EndOfStreamError =>
|
||||||
|
write!(fmt, "EndOfStreamError"),
|
||||||
|
DeserializeError::UnknownFieldError =>
|
||||||
|
write!(fmt, "UnknownFieldError"),
|
||||||
|
DeserializeError::MissingFieldError =>
|
||||||
|
write!(fmt, "MissingFieldError"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::de::Error for DeserializeError {
|
||||||
|
fn syntax_error() -> DeserializeError {
|
||||||
|
DeserializeError::SyntaxError
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> DeserializeError {
|
||||||
|
DeserializeError::EndOfStreamError
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unknown_field_error(_field: &str) -> DeserializeError {
|
||||||
|
DeserializeError::UnknownFieldError
|
||||||
|
}
|
||||||
|
|
||||||
|
fn missing_field_error(_field: &'static str) -> DeserializeError {
|
||||||
|
DeserializeError::MissingFieldError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DeserializeResult<T> = Result<T, DeserializeError>;
|
||||||
|
|
||||||
|
|
||||||
|
/// A Deserializer that reads bytes from a buffer.
|
||||||
|
///
|
||||||
|
/// This struct should rarely be used.
|
||||||
|
/// In most cases, prefer the `decode_from` function.
|
||||||
|
pub struct Deserializer<'a, R: 'a> {
|
||||||
|
reader: &'a mut R,
|
||||||
|
size_limit: SizeLimit,
|
||||||
|
read: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, R: Read> Deserializer<'a, R> {
|
||||||
|
pub fn new(r: &'a mut R, size_limit: SizeLimit) -> Deserializer<'a, R> {
|
||||||
|
Deserializer {
|
||||||
|
reader: r,
|
||||||
|
size_limit: size_limit,
|
||||||
|
read: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of bytes read from the contained Reader.
|
||||||
|
pub fn bytes_read(&self) -> u64 {
|
||||||
|
self.read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a, A> Deserializer<'a, A> {
|
||||||
|
fn read_bytes(&mut self, count: u64) -> Result<(), DeserializeError> {
|
||||||
|
self.read += count;
|
||||||
|
match self.size_limit {
|
||||||
|
SizeLimit::Infinite => Ok(()),
|
||||||
|
SizeLimit::Bounded(x) if self.read <= x => Ok(()),
|
||||||
|
SizeLimit::Bounded(_) => Err(DeserializeError::SizeLimit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_type<T>(&mut self) -> Result<(), DeserializeError> {
|
||||||
|
use std::mem::size_of;
|
||||||
|
self.read_bytes(size_of::<T>() as u64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_nums {
|
||||||
|
($ty:ty, $visitor_method:ident, $reader_method:ident) => {
|
||||||
|
#[inline]
|
||||||
|
fn $visitor_method<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
try!(self.read_type::<$ty>());
|
||||||
|
let value = try!(self.reader.$reader_method::<BigEndian>());
|
||||||
|
visitor.$visitor_method(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&mut self, _visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
Err(serde::de::Error::syntax_error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bool<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
let value: u8 = try!(serde::Deserialize::deserialize(self));
|
||||||
|
match value {
|
||||||
|
1 => visitor.visit_bool(true),
|
||||||
|
0 => visitor.visit_bool(false),
|
||||||
|
value => {
|
||||||
|
Err(DeserializeError::InvalidEncoding(InvalidEncoding {
|
||||||
|
desc: "invalid u8 when decoding bool",
|
||||||
|
detail: Some(format!("Expected 0 or 1, got {}", value))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u8<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
try!(self.read_type::<u8>());
|
||||||
|
visitor.visit_u8(try!(self.reader.read_u8()))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_nums!(u16, visit_u16, read_u16);
|
||||||
|
impl_nums!(u32, visit_u32, read_u32);
|
||||||
|
impl_nums!(u64, visit_u64, read_u64);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_usize<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
try!(self.read_type::<u64>());
|
||||||
|
let value = try!(self.reader.read_u64::<BigEndian>());
|
||||||
|
match num::cast(value) {
|
||||||
|
Some(value) => visitor.visit_usize(value),
|
||||||
|
None => Err(serde::de::Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i8<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
try!(self.read_type::<i8>());
|
||||||
|
visitor.visit_i8(try!(self.reader.read_i8()))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_nums!(i16, visit_i16, read_i16);
|
||||||
|
impl_nums!(i32, visit_i32, read_i32);
|
||||||
|
impl_nums!(i64, visit_i64, read_i64);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_isize<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
try!(self.read_type::<i64>());
|
||||||
|
let value = try!(self.reader.read_i64::<BigEndian>());
|
||||||
|
match num::cast(value) {
|
||||||
|
Some(value) => visitor.visit_isize(value),
|
||||||
|
None => Err(serde::de::Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_nums!(f32, visit_f32, read_f32);
|
||||||
|
impl_nums!(f64, visit_f64, read_f64);
|
||||||
|
|
||||||
|
fn visit_unit<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
visitor.visit_unit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_char<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
let error = DeserializeError::InvalidEncoding(InvalidEncoding {
|
||||||
|
desc: "Invalid char encoding",
|
||||||
|
detail: None
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut buf = [0];
|
||||||
|
|
||||||
|
let _ = try!(self.reader.read(&mut buf[..]));
|
||||||
|
let first_byte = buf[0];
|
||||||
|
let width = utf8_char_width(first_byte);
|
||||||
|
if width == 1 { return visitor.visit_char(first_byte as char) }
|
||||||
|
if width == 0 { return Err(error)}
|
||||||
|
|
||||||
|
let mut buf = [first_byte, 0, 0, 0];
|
||||||
|
{
|
||||||
|
let mut start = 1;
|
||||||
|
while start < width {
|
||||||
|
match try!(self.reader.read(&mut buf[start .. width])) {
|
||||||
|
n if n == width - start => break,
|
||||||
|
n if n < width - start => { start += n; }
|
||||||
|
_ => return Err(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = try!(match str::from_utf8(&buf[..width]).ok() {
|
||||||
|
Some(s) => Ok(s.chars().next().unwrap()),
|
||||||
|
None => Err(error)
|
||||||
|
});
|
||||||
|
|
||||||
|
try!(self.read_bytes(res.len_utf8() as u64));
|
||||||
|
visitor.visit_char(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_string<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
let len = try!(serde::Deserialize::deserialize(self));
|
||||||
|
try!(self.read_bytes(len));
|
||||||
|
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer));
|
||||||
|
|
||||||
|
match String::from_utf8(buffer) {
|
||||||
|
Ok(s) => visitor.visit_string(s),
|
||||||
|
Err(err) => Err(DeserializeError::InvalidEncoding(InvalidEncoding {
|
||||||
|
desc: "error while decoding utf8 string",
|
||||||
|
detail: Some(format!("Deserialize error: {}", err))
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_enum<V>(&mut self, _enum: &str, mut visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where V: serde::de::EnumVisitor,
|
||||||
|
{
|
||||||
|
visitor.visit(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_tuple<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
struct TupleVisitor<'a, 'b: 'a, R: Read + 'b>(&'a mut Deserializer<'b, R>);
|
||||||
|
|
||||||
|
impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, 'b, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
|
||||||
|
where T: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
let value = try!(serde::Deserialize::deserialize(self.0));
|
||||||
|
Ok(Some(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitor.visit_seq(TupleVisitor(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
self.visit_tuple(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_option<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
let value: u8 = try!(serde::de::Deserialize::deserialize(self));
|
||||||
|
match value {
|
||||||
|
0 => visitor.visit_none(),
|
||||||
|
1 => visitor.visit_some(self),
|
||||||
|
_ => Err(DeserializeError::InvalidEncoding(InvalidEncoding {
|
||||||
|
desc: "invalid tag when decoding Option",
|
||||||
|
detail: Some(format!("Expected 0 or 1, got {}", value))
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
struct SeqVisitor<'a, 'b: 'a, R: Read + 'b> {
|
||||||
|
deserializer: &'a mut Deserializer<'b, R>,
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, 'b, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
|
||||||
|
where T: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
if self.len > 0 {
|
||||||
|
self.len -= 1;
|
||||||
|
let value = try!(serde::Deserialize::deserialize(self.deserializer));
|
||||||
|
Ok(Some(value))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Self::Error> {
|
||||||
|
if self.len == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::syntax_error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = try!(serde::Deserialize::deserialize(self));
|
||||||
|
|
||||||
|
visitor.visit_seq(SeqVisitor { deserializer: self, len: len })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
struct MapVisitor<'a, 'b: 'a, R: Read + 'b> {
|
||||||
|
deserializer: &'a mut Deserializer<'b, R>,
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, 'b, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
|
||||||
|
where K: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
if self.len > 0 {
|
||||||
|
self.len -= 1;
|
||||||
|
let key = try!(serde::Deserialize::deserialize(self.deserializer));
|
||||||
|
Ok(Some(key))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
|
||||||
|
where V: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
let value = try!(serde::Deserialize::deserialize(self.deserializer));
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Self::Error> {
|
||||||
|
if self.len == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::syntax_error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = try!(serde::Deserialize::deserialize(self));
|
||||||
|
|
||||||
|
visitor.visit_map(MapVisitor { deserializer: self, len: len })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_named_map<V>(&mut self,
|
||||||
|
_name: &str,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
mut visitor: V) -> DeserializeResult<V::Value>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
struct StructVisitor<'a, 'b: 'a, R: Read + 'b> {
|
||||||
|
deserializer: &'a mut Deserializer<'b, R>,
|
||||||
|
index: usize,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for StructVisitor<'a, 'b, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
|
||||||
|
where K: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
if self.index < self.fields.len() {
|
||||||
|
let mut deserializer = self.index.into_deserializer();
|
||||||
|
self.index += 1;
|
||||||
|
|
||||||
|
let key = try!(serde::Deserialize::deserialize(&mut deserializer));
|
||||||
|
Ok(Some(key))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
|
||||||
|
where V: serde::de::Deserialize,
|
||||||
|
{
|
||||||
|
let value = try!(serde::Deserialize::deserialize(self.deserializer));
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Self::Error> {
|
||||||
|
if self.index < self.fields.len() {
|
||||||
|
Err(serde::de::Error::missing_field_error(self.fields[self.index]))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitor.visit_map(StructVisitor {
|
||||||
|
deserializer: self,
|
||||||
|
index: 0,
|
||||||
|
fields: fields,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> {
|
||||||
|
type Error = DeserializeError;
|
||||||
|
|
||||||
|
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
|
||||||
|
where V: serde::Deserialize,
|
||||||
|
{
|
||||||
|
let index: u32 = try!(serde::Deserialize::deserialize(self));
|
||||||
|
let mut deserializer = (index as usize).into_deserializer();
|
||||||
|
Ok(try!(serde::Deserialize::deserialize(&mut deserializer)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
serde::de::Deserializer::visit_named_seq(self, "", visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where V: serde::de::Visitor,
|
||||||
|
{
|
||||||
|
serde::de::Deserializer::visit_named_map(self, "", fields, visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_reader<R, T>(reader: &mut R, size_limit: SizeLimit) -> DeserializeResult<T>
|
||||||
|
where R: io::Read,
|
||||||
|
T: serde::Deserialize,
|
||||||
|
{
|
||||||
|
let mut deserializer = Deserializer::new(reader, size_limit);
|
||||||
|
serde::Deserialize::deserialize(&mut deserializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_slice<T>(bytes: &[u8], size_limit: SizeLimit) -> DeserializeResult<T>
|
||||||
|
where T: serde::Deserialize,
|
||||||
|
{
|
||||||
|
let mut reader = bytes;
|
||||||
|
from_reader(&mut reader, size_limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UTF8_CHAR_WIDTH: [u8; 256] = [
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
|
||||||
|
0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
|
||||||
|
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
|
||||||
|
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
|
||||||
|
];
|
||||||
|
|
||||||
|
fn utf8_char_width(b: u8) -> usize {
|
||||||
|
UTF8_CHAR_WIDTH[b as usize] as usize
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,8 @@ use std::ops::Deref;
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
use rustc_serialize::{Decodable, Decoder};
|
use rustc_serialize::{Decodable, Decoder};
|
||||||
|
|
||||||
|
use serde;
|
||||||
|
|
||||||
/// A struct for encoding nested reference types.
|
/// A struct for encoding nested reference types.
|
||||||
///
|
///
|
||||||
/// Encoding large objects by reference is really handy. For example,
|
/// Encoding large objects by reference is really handy. For example,
|
||||||
|
|
@ -151,6 +153,25 @@ impl <T: Decodable> Decodable for RefBox<'static, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T> serde::Serialize for RefBox<'a, T>
|
||||||
|
where T: serde::Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: serde::Serializer
|
||||||
|
{
|
||||||
|
serde::Serialize::serialize(&self.inner, serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: serde::Deserialize> serde::Deserialize for RefBox<'static, T> {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
||||||
|
where D: serde::Deserializer
|
||||||
|
{
|
||||||
|
let inner = try!(serde::Deserialize::deserialize(deserializer));
|
||||||
|
Ok(RefBox{ inner: inner })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> StrBox<'a> {
|
impl<'a> StrBox<'a> {
|
||||||
/// Creates a new StrBox that looks at a borrowed value.
|
/// Creates a new StrBox that looks at a borrowed value.
|
||||||
pub fn new(s: &'a str) -> StrBox<'a> {
|
pub fn new(s: &'a str) -> StrBox<'a> {
|
||||||
|
|
@ -226,6 +247,23 @@ impl Decodable for StrBox<'static> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> serde::Serialize for StrBox<'a> {
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: serde::Serializer
|
||||||
|
{
|
||||||
|
serde::Serialize::serialize(&self.inner, serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::Deserialize for StrBox<'static> {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
||||||
|
where D: serde::Deserializer
|
||||||
|
{
|
||||||
|
let inner = try!(serde::Deserialize::deserialize(deserializer));
|
||||||
|
Ok(StrBox{ inner: inner })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SliceBox
|
// SliceBox
|
||||||
//
|
//
|
||||||
|
|
@ -296,6 +334,25 @@ impl <T: Decodable> Decodable for SliceBox<'static, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T> serde::Serialize for SliceBox<'a, T>
|
||||||
|
where T: serde::Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: serde::Serializer
|
||||||
|
{
|
||||||
|
serde::Serialize::serialize(&self.inner, serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: serde::Deserialize> serde::Deserialize for SliceBox<'static, T> {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
||||||
|
where D: serde::Deserializer
|
||||||
|
{
|
||||||
|
let inner = try!(serde::Deserialize::deserialize(deserializer));
|
||||||
|
Ok(SliceBox{ inner: inner })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> {
|
impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> {
|
||||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -305,6 +362,21 @@ impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B>
|
||||||
|
where A: serde::Serialize,
|
||||||
|
B: serde::Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: serde::Serializer
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
&RefBoxInner::Ref(ref r) => serde::Serialize::serialize(r, serializer),
|
||||||
|
&RefBoxInner::Box(ref b) => serde::Serialize::serialize(b, serializer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl <A: ?Sized, B: Decodable> Decodable for RefBoxInner<'static, A, B> {
|
impl <A: ?Sized, B: Decodable> Decodable for RefBoxInner<'static, A, B> {
|
||||||
fn decode<D: Decoder>(d: &mut D) -> Result<RefBoxInner<'static, A, B>, D::Error> {
|
fn decode<D: Decoder>(d: &mut D) -> Result<RefBoxInner<'static, A, B>, D::Error> {
|
||||||
let decoded = try!(Decodable::decode(d));
|
let decoded = try!(Decodable::decode(d));
|
||||||
|
|
@ -312,6 +384,17 @@ impl <A: ?Sized, B: Decodable> Decodable for RefBoxInner<'static, A, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A: ?Sized, B> serde::Deserialize for RefBoxInner<'static, A, B>
|
||||||
|
where B: serde::Deserialize,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
||||||
|
where D: serde::Deserializer
|
||||||
|
{
|
||||||
|
let deserialized = try!(serde::Deserialize::deserialize(deserializer));
|
||||||
|
Ok(RefBoxInner::Box(deserialized))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl <'a, T> Deref for RefBox<'a, T> {
|
impl <'a, T> Deref for RefBox<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*
|
||||||
extern crate bincode;
|
extern crate bincode;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
|
||||||
|
|
@ -326,3 +327,4 @@ fn test_slicebox() {
|
||||||
fn test_multi_strings() {
|
fn test_multi_strings() {
|
||||||
assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok());
|
assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ use bincode::{
|
||||||
encoded_size,
|
encoded_size,
|
||||||
DecodingError,
|
DecodingError,
|
||||||
DecodingResult,
|
DecodingResult,
|
||||||
|
DeserializeError,
|
||||||
|
DeserializeResult,
|
||||||
RefBox,
|
RefBox,
|
||||||
StrBox,
|
StrBox,
|
||||||
SliceBox,
|
SliceBox,
|
||||||
|
|
@ -26,9 +28,8 @@ use bincode::{
|
||||||
use bincode::SizeLimit::{Infinite, Bounded};
|
use bincode::SizeLimit::{Infinite, Bounded};
|
||||||
|
|
||||||
fn the_same<V>(element: V)
|
fn the_same<V>(element: V)
|
||||||
where V: Encodable+Decodable+serde::Serialize+PartialEq+Debug+'static
|
where V: Encodable+Decodable+serde::Serialize+serde::Deserialize+PartialEq+Debug+'static
|
||||||
{
|
{
|
||||||
|
|
||||||
// Make sure that the bahavior isize correct when wrapping with a RefBox.
|
// Make sure that the bahavior isize correct when wrapping with a RefBox.
|
||||||
fn ref_box_correct<V>(v: &V) -> bool
|
fn ref_box_correct<V>(v: &V) -> bool
|
||||||
where V: Encodable+Decodable+PartialEq+Debug+'static
|
where V: Encodable+Decodable+PartialEq+Debug+'static
|
||||||
|
|
@ -48,9 +49,13 @@ fn the_same<V>(element: V)
|
||||||
assert_eq!(size, encoded.len() as u64);
|
assert_eq!(size, encoded.len() as u64);
|
||||||
assert!(ref_box_correct(&element));
|
assert!(ref_box_correct(&element));
|
||||||
|
|
||||||
let size = bincode::serialized_size(&element);
|
|
||||||
let serialized = bincode::to_vec(&element, Infinite).unwrap();
|
let serialized = bincode::to_vec(&element, Infinite).unwrap();
|
||||||
assert_eq!(encoded, serialized);
|
assert_eq!(encoded, serialized);
|
||||||
|
|
||||||
|
let deserialized = bincode::from_slice(&serialized[..], Infinite).unwrap();
|
||||||
|
assert_eq!(element, deserialized);
|
||||||
|
|
||||||
|
let size = bincode::serialized_size(&element);
|
||||||
assert_eq!(size, serialized.len() as u64);
|
assert_eq!(size, serialized.len() as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,16 +66,19 @@ fn test_numbers() {
|
||||||
the_same(5u16);
|
the_same(5u16);
|
||||||
the_same(5u32);
|
the_same(5u32);
|
||||||
the_same(5u64);
|
the_same(5u64);
|
||||||
|
the_same(5usize);
|
||||||
// signed positive
|
// signed positive
|
||||||
the_same(5i8);
|
the_same(5i8);
|
||||||
the_same(5i16);
|
the_same(5i16);
|
||||||
the_same(5i32);
|
the_same(5i32);
|
||||||
the_same(5i64);
|
the_same(5i64);
|
||||||
|
the_same(5isize);
|
||||||
// signed negative
|
// signed negative
|
||||||
the_same(-5i8);
|
the_same(-5i8);
|
||||||
the_same(-5i16);
|
the_same(-5i16);
|
||||||
the_same(-5i32);
|
the_same(-5i32);
|
||||||
the_same(-5i64);
|
the_same(-5i64);
|
||||||
|
the_same(-5isize);
|
||||||
// floating
|
// floating
|
||||||
the_same(-100f32);
|
the_same(-100f32);
|
||||||
the_same(0f32);
|
the_same(0f32);
|
||||||
|
|
@ -94,7 +102,7 @@ fn test_tuple() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_struct() {
|
fn test_basic_struct() {
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
struct Easy {
|
struct Easy {
|
||||||
x: isize,
|
x: isize,
|
||||||
s: String,
|
s: String,
|
||||||
|
|
@ -105,13 +113,13 @@ fn test_basic_struct() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_struct() {
|
fn test_nested_struct() {
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
struct Easy {
|
struct Easy {
|
||||||
x: isize,
|
x: isize,
|
||||||
s: String,
|
s: String,
|
||||||
y: usize
|
y: usize
|
||||||
}
|
}
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
struct Nest {
|
struct Nest {
|
||||||
f: Easy,
|
f: Easy,
|
||||||
b: usize,
|
b: usize,
|
||||||
|
|
@ -127,22 +135,22 @@ fn test_nested_struct() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_struct_tuple() {
|
fn test_struct_tuple() {
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
struct TubStr(usize, String, f32);
|
struct TubStr(usize, String, f32);
|
||||||
|
|
||||||
the_same(TubStr(5, "hello".to_string(), 3.2));
|
the_same(TubStr(5, "hello".to_string(), 3.2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn option() {
|
fn test_option() {
|
||||||
the_same(Some(5usize));
|
the_same(Some(5usize));
|
||||||
the_same(Some("foo bar".to_string()));
|
the_same(Some("foo bar".to_string()));
|
||||||
the_same(None::<usize>);
|
the_same(None::<usize>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enm() {
|
fn test_enum() {
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
enum TestEnum {
|
enum TestEnum {
|
||||||
NoArg,
|
NoArg,
|
||||||
OneArg(usize),
|
OneArg(usize),
|
||||||
|
|
@ -153,10 +161,9 @@ fn enm() {
|
||||||
the_same(TestEnum::AnotherNoArg);
|
the_same(TestEnum::AnotherNoArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn struct_enum() {
|
fn test_struct_enum() {
|
||||||
#[derive(RustcEncodable, RustcDecodable, Serialize, PartialEq, Debug)]
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
|
||||||
enum TestEnum {
|
enum TestEnum {
|
||||||
NoArg,
|
NoArg,
|
||||||
OneArg(usize),
|
OneArg(usize),
|
||||||
|
|
@ -172,7 +179,7 @@ fn struct_enum() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn many() {
|
fn test_vec() {
|
||||||
let v: Vec<u8> = vec![];
|
let v: Vec<u8> = vec![];
|
||||||
the_same(v);
|
the_same(v);
|
||||||
the_same(vec![1u64]);
|
the_same(vec![1u64]);
|
||||||
|
|
@ -180,7 +187,7 @@ fn many() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map() {
|
fn test_map() {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert(4u64, "foo".to_string());
|
m.insert(4u64, "foo".to_string());
|
||||||
m.insert(0u64, "bar".to_string());
|
m.insert(0u64, "bar".to_string());
|
||||||
|
|
@ -188,18 +195,17 @@ fn map() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn boole() {
|
fn test_bool() {
|
||||||
the_same(true);
|
the_same(true);
|
||||||
the_same(false);
|
the_same(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unicode() {
|
fn test_unicode() {
|
||||||
the_same("å".to_string());
|
the_same("å".to_string());
|
||||||
the_same("aåååååååa".to_string());
|
the_same("aåååååååa".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decoding_errors() {
|
fn decoding_errors() {
|
||||||
fn isize_invalid_encoding<T>(res: DecodingResult<T>) {
|
fn isize_invalid_encoding<T>(res: DecodingResult<T>) {
|
||||||
|
|
@ -223,6 +229,28 @@ fn decoding_errors() {
|
||||||
isize_invalid_encoding(decode::<Option<u8>>(&vec![5, 0][..]));
|
isize_invalid_encoding(decode::<Option<u8>>(&vec![5, 0][..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserializing_errors() {
|
||||||
|
fn isize_invalid_deserialize<T: Debug>(res: DeserializeResult<T>) {
|
||||||
|
match res {
|
||||||
|
Err(DeserializeError::InvalidEncoding(_)) => {},
|
||||||
|
Err(DeserializeError::SyntaxError) => {},
|
||||||
|
_ => panic!("Expecting InvalidEncoding, got {:?}", res),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isize_invalid_deserialize(bincode::from_slice::<bool>(&vec![0xA][..], Infinite));
|
||||||
|
isize_invalid_deserialize(bincode::from_slice::<String>(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..], Infinite));
|
||||||
|
// Out-of-bounds variant
|
||||||
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)]
|
||||||
|
enum Test {
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
};
|
||||||
|
isize_invalid_deserialize(bincode::from_slice::<Test>(&vec![0, 0, 0, 5][..], Infinite));
|
||||||
|
isize_invalid_deserialize(bincode::from_slice::<Option<u8>>(&vec![5, 0][..], Infinite));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_big_decode() {
|
fn too_big_decode() {
|
||||||
let encoded = vec![0,0,0,3];
|
let encoded = vec![0,0,0,3];
|
||||||
|
|
@ -236,6 +264,17 @@ fn too_big_decode() {
|
||||||
assert!(decoded.is_ok());
|
assert!(decoded.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn too_big_deserialize() {
|
||||||
|
let serialized = vec![0,0,0,3];
|
||||||
|
let deserialized: Result<u32, _> = bincode::from_slice(&serialized[..], Bounded(3));
|
||||||
|
assert!(deserialized.is_err());
|
||||||
|
|
||||||
|
let serialized = vec![0,0,0,3];
|
||||||
|
let deserialized: Result<u32, _> = bincode::from_slice(&serialized[..], Bounded(4));
|
||||||
|
assert!(deserialized.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_big_char_decode() {
|
fn too_big_char_decode() {
|
||||||
let encoded = vec![0x41];
|
let encoded = vec![0x41];
|
||||||
|
|
@ -245,6 +284,14 @@ fn too_big_char_decode() {
|
||||||
assert_eq!(decoded.unwrap(), 'A');
|
assert_eq!(decoded.unwrap(), 'A');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn too_big_char_deserialize() {
|
||||||
|
let serialized = vec![0x41];
|
||||||
|
let deserialized: Result<char, _> = bincode::from_slice(&serialized[..], Bounded(1));
|
||||||
|
assert!(deserialized.is_ok());
|
||||||
|
assert_eq!(deserialized.unwrap(), 'A');
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_big_encode() {
|
fn too_big_encode() {
|
||||||
assert!(encode(&0u32, Bounded(3)).is_err());
|
assert!(encode(&0u32, Bounded(3)).is_err());
|
||||||
|
|
@ -254,6 +301,15 @@ fn too_big_encode() {
|
||||||
assert!(encode(&"abcde", Bounded(8 + 5)).is_ok());
|
assert!(encode(&"abcde", Bounded(8 + 5)).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn too_big_serialize() {
|
||||||
|
assert!(bincode::to_vec(&0u32, Bounded(3)).is_err());
|
||||||
|
assert!(bincode::to_vec(&0u32, Bounded(4)).is_ok());
|
||||||
|
|
||||||
|
assert!(bincode::to_vec(&"abcde", Bounded(8 + 4)).is_err());
|
||||||
|
assert!(bincode::to_vec(&"abcde", Bounded(8 + 5)).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encoded_size() {
|
fn test_encoded_size() {
|
||||||
assert!(encoded_size(&0u8) == 1);
|
assert!(encoded_size(&0u8) == 1);
|
||||||
|
|
@ -266,6 +322,21 @@ fn test_encoded_size() {
|
||||||
assert!(encoded_size(&"a") == 8 + 1);
|
assert!(encoded_size(&"a") == 8 + 1);
|
||||||
|
|
||||||
assert!(encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
|
assert!(encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialized_size() {
|
||||||
|
assert!(bincode::serialized_size(&0u8) == 1);
|
||||||
|
assert!(bincode::serialized_size(&0u16) == 2);
|
||||||
|
assert!(bincode::serialized_size(&0u32) == 4);
|
||||||
|
assert!(bincode::serialized_size(&0u64) == 8);
|
||||||
|
|
||||||
|
// length isize stored as u64
|
||||||
|
assert!(bincode::serialized_size(&"") == 8);
|
||||||
|
assert!(bincode::serialized_size(&"a") == 8 + 1);
|
||||||
|
|
||||||
|
assert!(bincode::serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -274,7 +345,7 @@ fn encode_box() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_refbox() {
|
fn test_refbox_encode() {
|
||||||
let large_object = vec![1u32,2,3,4,5,6];
|
let large_object = vec![1u32,2,3,4,5,6];
|
||||||
let mut large_map = HashMap::new();
|
let mut large_map = HashMap::new();
|
||||||
large_map.insert(1, 2);
|
large_map.insert(1, 2);
|
||||||
|
|
@ -310,7 +381,43 @@ fn test_refbox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_strbox() {
|
fn test_refbox_serialize() {
|
||||||
|
let large_object = vec![1u32,2,3,4,5,6];
|
||||||
|
let mut large_map = HashMap::new();
|
||||||
|
large_map.insert(1, 2);
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)]
|
||||||
|
enum Message<'a> {
|
||||||
|
M1(RefBox<'a, Vec<u32>>),
|
||||||
|
M2(RefBox<'a, HashMap<u32, u32>>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 1
|
||||||
|
{
|
||||||
|
let serialized = bincode::to_vec(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
|
||||||
|
let deserialized: Message<'static> = bincode::from_slice(&serialized[..], Infinite).unwrap();
|
||||||
|
|
||||||
|
match deserialized {
|
||||||
|
Message::M1(b) => assert!(b.take().deref() == &large_object),
|
||||||
|
_ => assert!(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 2
|
||||||
|
{
|
||||||
|
let serialized = bincode::to_vec(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
|
||||||
|
let deserialized: Message<'static> = bincode::from_slice(&serialized[..], Infinite).unwrap();
|
||||||
|
|
||||||
|
match deserialized {
|
||||||
|
Message::M2(b) => assert!(b.take().deref() == &large_map),
|
||||||
|
_ => assert!(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_strbox_encode() {
|
||||||
let strx: &'static str = "hello world";
|
let strx: &'static str = "hello world";
|
||||||
let encoded = encode(&StrBox::new(strx), Infinite).unwrap();
|
let encoded = encode(&StrBox::new(strx), Infinite).unwrap();
|
||||||
let decoded: StrBox<'static> = decode(&encoded[..]).unwrap();
|
let decoded: StrBox<'static> = decode(&encoded[..]).unwrap();
|
||||||
|
|
@ -319,7 +426,16 @@ fn test_strbox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slicebox() {
|
fn test_strbox_serialize() {
|
||||||
|
let strx: &'static str = "hello world";
|
||||||
|
let serialized = bincode::to_vec(&StrBox::new(strx), Infinite).unwrap();
|
||||||
|
let deserialized: StrBox<'static> = bincode::from_slice(&serialized[..], Infinite).unwrap();
|
||||||
|
let stringx: String = deserialized.take();
|
||||||
|
assert!(strx == &stringx[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_slicebox_encode() {
|
||||||
let slice = [1u32, 2, 3 ,4, 5];
|
let slice = [1u32, 2, 3 ,4, 5];
|
||||||
let encoded = encode(&SliceBox::new(&slice), Infinite).unwrap();
|
let encoded = encode(&SliceBox::new(&slice), Infinite).unwrap();
|
||||||
let decoded: SliceBox<'static, u32> = decode(&encoded[..]).unwrap();
|
let decoded: SliceBox<'static, u32> = decode(&encoded[..]).unwrap();
|
||||||
|
|
@ -332,6 +448,24 @@ fn test_slicebox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multi_strings() {
|
fn test_slicebox_serialize() {
|
||||||
|
let slice = [1u32, 2, 3 ,4, 5];
|
||||||
|
let serialized = bincode::to_vec(&SliceBox::new(&slice), Infinite).unwrap();
|
||||||
|
let deserialized: SliceBox<'static, u32> = bincode::from_slice(&serialized[..], Infinite).unwrap();
|
||||||
|
{
|
||||||
|
let sb: &[u32] = &deserialized;
|
||||||
|
assert!(slice == sb);
|
||||||
|
}
|
||||||
|
let vecx: Vec<u32> = deserialized.take();
|
||||||
|
assert!(slice == &vecx[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multi_strings_encode() {
|
||||||
assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok());
|
assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multi_strings_serialize() {
|
||||||
|
assert!(bincode::to_vec(&("foo", "bar", "baz"), Infinite).is_ok());
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue