Get serde working

This commit is contained in:
Erick Tryzelaar 2015-07-01 20:19:34 -07:00
parent b206032ff1
commit 0d6b8a48b6
6 changed files with 850 additions and 22 deletions

View File

@ -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 = "*"

View File

@ -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.
/// ///

599
src/reader_serde.rs Normal file
View File

@ -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
}

View File

@ -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;

View File

@ -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());
} }
*/

View File

@ -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());
}