diff --git a/.travis.yml b/.travis.yml index 42fe126..35b04d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,19 +3,3 @@ rust: - stable - beta - nightly - -after_success: | - [ $TRAVIS_BRANCH = master ] && - [ $TRAVIS_PULL_REQUEST = false ] && - cargo doc && - echo "" > target/doc/index.html && - sudo pip install ghp-import && - ghp-import -n target/doc && - git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages -env: - global: - - secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI= -matrix: - allow_failures: - - rust: stable - - rust: beta diff --git a/Cargo.toml b/Cargo.toml index 83d96f2..2cb8a1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,21 @@ [package] name = "bincode" -version = "0.5.1" -authors = ["Ty Overby ", "Francesco Mazzoli "] +version = "1.0.0-alpha4" +authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Daniel Griffen"] repository = "https://github.com/TyOverby/bincode" -documentation = "http://tyoverby.github.io/bincode/bincode/" +documentation = "https://docs.rs/bincode" keywords = ["binary", "encode", "decode", "serialize", "deserialize"] license = "MIT" -description = "A binary serialization / deserialization strategy and implementation." +description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!" [dependencies] -rustc-serialize = "0.3.*" -byteorder = "0.4.*" -num = "0.1.*" -serde = "0.7.*" +byteorder = "1.0.0" +num-traits = "0.1.32" + +[dependencies.serde] +version = "0.9.*" [dev-dependencies] -serde_macros = "0.7.*" +serde_derive = "0.9.*" diff --git a/README.md b/README.md index ffc1658..f13ec72 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,13 @@ perfectly with other stream-based apis such as rust files, network streams, and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression library. -[Api Documentation](http://tyoverby.github.io/bincode/bincode/) +## [Api Documentation](http://tyoverby.github.io/bincode/bincode/) + +## Bincode in the wild + +* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages. +* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging. +* [servo/icp-channel](https://github.com/servo/ipc-channel): Ipc-Channel uses Bincode to send structs between processes using a channel-like API. ## Example ```rust diff --git a/changelist.org b/changelist.org new file mode 100644 index 0000000..761068b --- /dev/null +++ b/changelist.org @@ -0,0 +1,18 @@ +* 1.0.0 +** Removed depricated rustc-serialize support + Rustc-serialize was a stopgap until projects like Serde were able to catch up. + With macros stabilization on its way, we are able to switch to serde without any + big user-friendliness issues. Major congratulations to Serde for coming this far! + +** Moved Refbox, Strbox and Slicebox into a "refbox" module + Refbox, Strbox and Slicebox are still an integral piece of bincode, but since + they are mainly used by power-users, this move will make the crate API more organized + and easier for new users to understand. + +** Upgraded to Serde 0.9.* + Serde 0.9.* gives us a better API surface area and allows use of procedural macros for + deriving serialize and deserialize implemenetations. + +** Moved serde functions into global module + Since serde is the only supported serialization mechanism, it makes sense to have these + functions available at the top level. diff --git a/examples/basic.rs b/examples/basic.rs index 670f6bc..c5d9d3e 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,5 +1,6 @@ +/* extern crate bincode; -extern crate rustc_serialize; +extern crate use bincode::SizeLimit; use bincode::rustc_serialize::{encode, decode}; @@ -29,3 +30,6 @@ fn main() { assert!(world == decoded); } + */ + +fn main() {} diff --git a/src/lib.rs b/src/lib.rs index 1baf135..2982637 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,17 +16,16 @@ //! ### Using Basic Functions //! //! ```rust -//! #![allow(unstable)] //! extern crate bincode; -//! use bincode::rustc_serialize::{encode, decode}; +//! use bincode::{serialize, deserialize}; //! fn main() { //! // The object that we will serialize. //! let target = Some("hello world".to_string()); //! // The maximum size of the encoded message. //! let limit = bincode::SizeLimit::Bounded(20); //! -//! let encoded: Vec = encode(&target, limit).unwrap(); -//! let decoded: Option = decode(&encoded[..]).unwrap(); +//! let encoded: Vec = serialize(&target, limit).unwrap(); +//! let decoded: Option = deserialize(&encoded[..]).unwrap(); //! assert_eq!(target, decoded); //! } //! ``` @@ -37,17 +36,70 @@ #![doc(html_logo_url = "./icon.png")] -extern crate rustc_serialize as rustc_serialize_crate; extern crate byteorder; -extern crate num; +extern crate num_traits; extern crate serde as serde_crate; +pub mod refbox; +mod serde; -pub use refbox::{RefBox, StrBox, SliceBox}; +pub mod endian_choice { + pub use super::serde::{serialize, serialize_into, deserialize, deserialize_from}; +} -mod refbox; -pub mod rustc_serialize; -pub mod serde; +use std::io::{Read, Write}; + +pub use serde::{Deserializer, Serializer, ErrorKind, Error, Result, serialized_size, serialized_size_bounded}; + +/// Deserializes a slice of bytes into an object. +/// +/// This method does not have a size-limit because if you already have the bytes +/// in memory, then you don't gain anything by having a limiter. +pub fn deserialize(bytes: &[u8]) -> serde::Result + where T: serde_crate::Deserialize, +{ + serde::deserialize::<_, byteorder::LittleEndian>(bytes) +} + +/// Deserializes an object directly from a `Buffer`ed Reader. +/// +/// If the provided `SizeLimit` is reached, the deserialization will bail immediately. +/// A SizeLimit can help prevent an attacker from flooding your server with +/// a neverending stream of values that runs your server out of memory. +/// +/// If this returns an `Error`, assume that the buffer that you passed +/// in is in an invalid state, as the error could be returned during any point +/// in the reading. +pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> serde::Result + where R: Read, + T: serde_crate::Deserialize, +{ + serde::deserialize_from::<_, _, byteorder::LittleEndian>(reader, size_limit) +} + +/// Serializes an object directly into a `Writer`. +/// +/// If the serialization would take more bytes than allowed by `size_limit`, an error +/// is returned and *no bytes* will be written into the `Writer`. +/// +/// If this returns an `Error` (other than SizeLimit), assume that the +/// writer is in an invalid state, as writing could bail out in the middle of +/// serializing. +pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> serde::Result<()> + where W: Write, T: serde_crate::Serialize +{ + serde::serialize_into::<_, _, byteorder::LittleEndian>(writer, value, size_limit) +} + +/// Serializes a serializable object into a `Vec` of bytes. +/// +/// If the serialization would take more bytes than allowed by `size_limit`, +/// an error is returned. +pub fn serialize(value: &T, size_limit: SizeLimit) -> serde::Result> + where T: serde_crate::Serialize +{ + serde::serialize::<_, byteorder::LittleEndian>(value, size_limit) +} /// A limit on the amount of bytes that can be read or written. /// @@ -66,10 +118,9 @@ pub mod serde; /// that is larger than your decoder expects. By supplying a size limit to an /// encoding function, the encoder will verify that the structure can be encoded /// within that limit. This verification occurs before any bytes are written to -/// the Writer, so recovering from an the error is easy. +/// the Writer, so recovering from an error is easy. #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] pub enum SizeLimit { Infinite, Bounded(u64) } - diff --git a/src/refbox.rs b/src/refbox.rs index b115357..be663f9 100644 --- a/src/refbox.rs +++ b/src/refbox.rs @@ -1,8 +1,6 @@ use std::boxed::Box; use std::ops::Deref; -use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder}; - use serde_crate as serde; /// A struct for encoding nested reference types. @@ -139,32 +137,18 @@ impl RefBox<'static, T> { } } - -impl <'a, T: Encodable> Encodable for RefBox<'a, T> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} - -impl Decodable for RefBox<'static, T> { - fn decode(d: &mut D) -> Result, D::Error> { - let inner = try!(Decodable::decode(d)); - Ok(RefBox{inner: inner}) - } -} - impl<'a, T> serde::Serialize for RefBox<'a, T> where T: serde::Serialize, { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serde::Serialize::serialize(&self.inner, serializer) } } -impl serde::Deserialize for RefBox<'static, T> { - fn deserialize(deserializer: &mut D) -> Result +impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let inner = try!(serde::Deserialize::deserialize(deserializer)); @@ -234,21 +218,9 @@ impl StrBox<'static> { } } -impl <'a> Encodable for StrBox<'a> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} - -impl Decodable for StrBox<'static> { - fn decode(d: &mut D) -> Result, D::Error> { - let inner: RefBoxInner<'static, str, String> = try!(Decodable::decode(d)); - Ok(StrBox{inner: inner}) - } -} impl<'a> serde::Serialize for StrBox<'a> { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serde::Serialize::serialize(&self.inner, serializer) @@ -256,7 +228,7 @@ impl<'a> serde::Serialize for StrBox<'a> { } impl serde::Deserialize for StrBox<'static> { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let inner = try!(serde::Deserialize::deserialize(deserializer)); @@ -321,31 +293,19 @@ impl SliceBox<'static, T> { } } -impl <'a, T: Encodable> Encodable for SliceBox<'a, T> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} - -impl Decodable for SliceBox<'static, T> { - fn decode(d: &mut D) -> Result, D::Error> { - let inner: RefBoxInner<'static, [T], Vec> = try!(Decodable::decode(d)); - Ok(SliceBox{inner: inner}) - } -} impl<'a, T> serde::Serialize for SliceBox<'a, T> where T: serde::Serialize, { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serde::Serialize::serialize(&self.inner, serializer) } } -impl serde::Deserialize for SliceBox<'static, T> { - fn deserialize(deserializer: &mut D) -> Result +impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let inner = try!(serde::Deserialize::deserialize(deserializer)); @@ -353,20 +313,12 @@ impl serde::Deserialize for SliceBox<'static, T> { } } -impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - match self { - &RefBoxInner::Ref(ref r) => r.encode(s), - &RefBoxInner::Box(ref b) => b.encode(s) - } - } -} impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> where A: serde::Serialize, B: serde::Serialize, { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { match self { @@ -377,17 +329,10 @@ impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> } -impl Decodable for RefBoxInner<'static, A, B> { - fn decode(d: &mut D) -> Result, D::Error> { - let decoded = try!(Decodable::decode(d)); - Ok(RefBoxInner::Box(decoded)) - } -} - -impl serde::Deserialize for RefBoxInner<'static, A, B> +impl<'a, A: ?Sized, B> serde::Deserialize for RefBoxInner<'a, A, B> where B: serde::Deserialize, { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let deserialized = try!(serde::Deserialize::deserialize(deserializer)); diff --git a/src/rustc_serialize/mod.rs b/src/rustc_serialize/mod.rs deleted file mode 100644 index b7565ed..0000000 --- a/src/rustc_serialize/mod.rs +++ /dev/null @@ -1,103 +0,0 @@ -//! A collection of serialization and deserialization functions -//! that use the `rustc_serialize` crate for the encodable and decodable -//! implementation. - -use rustc_serialize_crate::{Encodable, Decodable}; -use std::io::{Write, Read}; -use ::SizeLimit; - -pub use self::writer::{SizeChecker, EncoderWriter, EncodingResult, EncodingError}; -pub use self::reader::{DecoderReader, DecodingResult, DecodingError}; - -mod reader; -mod writer; - -/// Encodes an encodable object into a `Vec` of bytes. -/// -/// If the encoding would take more bytes than allowed by `size_limit`, -/// an error is returned. -pub fn encode(t: &T, size_limit: SizeLimit) -> EncodingResult> { - // Since we are putting values directly into a vector, we can do size - // computation out here and pre-allocate a buffer of *exactly* - // the right size. - let mut w = if let SizeLimit::Bounded(l) = size_limit { - let actual_size = encoded_size_bounded(t, l); - let actual_size = try!(actual_size.ok_or(EncodingError::SizeLimit)); - Vec::with_capacity(actual_size as usize) - } else { - vec![] - }; - - match encode_into(t, &mut w, SizeLimit::Infinite) { - Ok(()) => Ok(w), - Err(e) => Err(e) - } -} - -/// Decodes a slice of bytes into an object. -/// -/// This method does not have a size-limit because if you already have the bytes -/// in memory, then you don't gain anything by having a limiter. -pub fn decode(b: &[u8]) -> DecodingResult { - let mut b = b; - decode_from(&mut b, SizeLimit::Infinite) -} - -/// Encodes an object directly into a `Writer`. -/// -/// If the encoding would take more bytes than allowed by `size_limit`, an error -/// is returned and *no bytes* will be written into the `Writer`. -/// -/// If this returns an `EncodingError` (other than SizeLimit), assume that the -/// writer is in an invalid state, as writing could bail out in the middle of -/// encoding. -pub fn encode_into(t: &T, - w: &mut W, - size_limit: SizeLimit) - -> EncodingResult<()> { - try!(match size_limit { - SizeLimit::Infinite => Ok(()), - SizeLimit::Bounded(x) => { - let mut size_checker = SizeChecker::new(x); - t.encode(&mut size_checker) - } - }); - - t.encode(&mut writer::EncoderWriter::new(w)) -} - -/// Decoes an object directly from a `Buffer`ed Reader. -/// -/// If the provided `SizeLimit` is reached, the decode will bail immediately. -/// A SizeLimit can help prevent an attacker from flooding your server with -/// a neverending stream of values that runs your server out of memory. -/// -/// If this returns an `DecodingError`, assume that the buffer that you passed -/// in is in an invalid state, as the error could be returned during any point -/// in the reading. -pub fn decode_from(r: &mut R, size_limit: SizeLimit) -> DecodingResult { - Decodable::decode(&mut reader::DecoderReader::new(r, size_limit)) -} - - -/// Returns the size that an object would be if encoded using bincode. -/// -/// This is used internally as part of the check for encode_into, but it can -/// be useful for preallocating buffers if thats your style. -pub fn encoded_size(t: &T) -> u64 { - use std::u64::MAX; - let mut size_checker = SizeChecker::new(MAX); - t.encode(&mut size_checker).ok(); - size_checker.written -} - -/// Given a maximum size limit, check how large an object would be if it -/// were to be encoded. -/// -/// If it can be encoded in `max` or fewer bytes, that number will be returned -/// inside `Some`. If it goes over bounds, then None is returned. -pub fn encoded_size_bounded(t: &T, max: u64) -> Option { - let mut size_checker = SizeChecker::new(max); - t.encode(&mut size_checker).ok().map(|_| size_checker.written) -} - diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs deleted file mode 100644 index d3dbfb3..0000000 --- a/src/rustc_serialize/reader.rs +++ /dev/null @@ -1,397 +0,0 @@ -use std::io::Read; -use std::io::Error as IoError; -use std::error::Error; -use std::fmt; -use std::convert::From; - -use rustc_serialize_crate::Decoder; - -use byteorder::{BigEndian, ReadBytesExt}; -use byteorder::Error as ByteOrderError; -use ::SizeLimit; - -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct InvalidEncoding { - desc: &'static str, - detail: Option, -} - -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 DecodingError { - /// 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 -} - -impl fmt::Display for DecodingError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - DecodingError::IoError(ref ioerr) => - write!(fmt, "IoError: {}", ioerr), - DecodingError::InvalidEncoding(ref ib) => - write!(fmt, "InvalidEncoding: {}", ib), - DecodingError::SizeLimit => - write!(fmt, "SizeLimit") - } - } -} - -pub type DecodingResult = Result; - -fn wrap_io(err: ByteOrderError) -> DecodingError { - match err { - ByteOrderError::Io(ioe) => DecodingError::IoError(ioe), - ByteOrderError::UnexpectedEOF => - DecodingError::InvalidEncoding(InvalidEncoding { - desc: "Unexpected EOF while reading a multi-byte number", - detail: None - }) - } -} - -impl Error for DecodingError { - fn description(&self) -> &str { - match *self { - DecodingError::IoError(ref err) => Error::description(err), - DecodingError::InvalidEncoding(ref ib) => ib.desc, - DecodingError::SizeLimit => "the size limit for decoding has been reached" - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - DecodingError::IoError(ref err) => err.cause(), - DecodingError::InvalidEncoding(_) => None, - DecodingError::SizeLimit => None - } - } -} - -impl From for DecodingError { - fn from(err: IoError) -> DecodingError { - DecodingError::IoError(err) - } -} - -/// A Decoder that reads bytes from a buffer. -/// -/// This struct should rarely be used. -/// In most cases, prefer the `decode_from` function. -/// -/// ```rust,ignore -/// let dr = bincode::rustc_serialize::DecoderReader::new(&mut some_reader, SizeLimit::Infinite); -/// let result: T = Decodable::decode(&mut dr); -/// let bytes_read = dr.bytes_read(); -/// ``` -pub struct DecoderReader<'a, R: 'a> { - reader: &'a mut R, - size_limit: SizeLimit, - read: u64 -} - -impl<'a, R: Read> DecoderReader<'a, R> { - pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> { - DecoderReader { - 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> DecoderReader<'a, A> { - fn read_bytes(&mut self, count: u64) -> Result<(), DecodingError> { - self.read += count; - match self.size_limit { - SizeLimit::Infinite => Ok(()), - SizeLimit::Bounded(x) if self.read <= x => Ok(()), - SizeLimit::Bounded(_) => Err(DecodingError::SizeLimit) - } - } - - fn read_type(&mut self) -> Result<(), DecodingError> { - use std::mem::size_of; - self.read_bytes(size_of::() as u64) - } -} - -impl<'a, R: Read> Decoder for DecoderReader<'a, R> { - type Error = DecodingError; - - fn read_nil(&mut self) -> DecodingResult<()> { - Ok(()) - } - fn read_usize(&mut self) -> DecodingResult { - Ok(try!(self.read_u64().map(|x| x as usize))) - } - fn read_u64(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_u64::().map_err(wrap_io) - } - fn read_u32(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_u32::().map_err(wrap_io) - } - fn read_u16(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_u16::().map_err(wrap_io) - } - fn read_u8(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_u8().map_err(wrap_io) - } - fn read_isize(&mut self) -> DecodingResult { - self.read_i64().map(|x| x as isize) - } - fn read_i64(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_i64::().map_err(wrap_io) - } - fn read_i32(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_i32::().map_err(wrap_io) - } - fn read_i16(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_i16::().map_err(wrap_io) - } - fn read_i8(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_i8().map_err(wrap_io) - } - fn read_bool(&mut self) -> DecodingResult { - let x = try!(self.read_i8()); - match x { - 1 => Ok(true), - 0 => Ok(false), - _ => Err(DecodingError::InvalidEncoding(InvalidEncoding{ - desc: "invalid u8 when decoding bool", - detail: Some(format!("Expected 0 or 1, got {}", x)) - })), - } - } - fn read_f64(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_f64::().map_err(wrap_io) - } - fn read_f32(&mut self) -> DecodingResult { - try!(self.read_type::()); - self.reader.read_f32::().map_err(wrap_io) - } - fn read_char(&mut self) -> DecodingResult { - use std::str; - - let error = DecodingError::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 Ok(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)); - Ok(res) - } - - fn read_str(&mut self) -> DecodingResult { - let len = try!(self.read_usize()); - try!(self.read_bytes(len as u64)); - - let mut buff = Vec::new(); - try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buff)); - match String::from_utf8(buff) { - Ok(s) => Ok(s), - Err(err) => Err(DecodingError::InvalidEncoding(InvalidEncoding { - desc: "error while decoding utf8 string", - detail: Some(format!("Decoding error: {}", err)) - })), - } - } - fn read_enum(&mut self, _: &str, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_enum_variant(&mut self, names: &[&str], mut f: F) -> DecodingResult - where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult - { - let id = try!(self.read_u32()); - let id = id as usize; - if id >= names.len() { - Err(DecodingError::InvalidEncoding(InvalidEncoding { - desc: "out of bounds tag when reading enum variant", - detail: Some(format!("Expected tag < {}, got {}", names.len(), id)) - })) - } else { - f(self, id) - } - } - fn read_enum_variant_arg(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodingResult - where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult - { - self.read_enum_variant(names, f) - } - fn read_enum_struct_variant_field(&mut self, - _: &str, - f_idx: usize, - f: F) - -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - self.read_enum_variant_arg(f_idx, f) - } - fn read_struct(&mut self, _: &str, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_struct_field(&mut self, _: &str, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_tuple(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_tuple_arg(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_tuple_struct(&mut self, _: &str, len: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - self.read_tuple(len, f) - } - fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - self.read_tuple_arg(a_idx, f) - } - fn read_option(&mut self, mut f: F) -> DecodingResult - where F: FnMut(&mut DecoderReader<'a, R>, bool) -> DecodingResult - { - let x = try!(self.read_u8()); - match x { - 1 => f(self, true), - 0 => f(self, false), - _ => Err(DecodingError::InvalidEncoding(InvalidEncoding { - desc: "invalid tag when decoding Option", - detail: Some(format!("Expected 0 or 1, got {}", x)) - })), - } - } - fn read_seq(&mut self, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult - { - let len = try!(self.read_usize()); - f(self, len) - } - fn read_seq_elt(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_map(&mut self, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult - { - let len = try!(self.read_usize()); - f(self, len) - } - fn read_map_elt_key(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn read_map_elt_val(&mut self, _: usize, f: F) -> DecodingResult - where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult - { - f(self) - } - fn error(&mut self, err: &str) -> DecodingError { - DecodingError::InvalidEncoding(InvalidEncoding { - desc: "user-induced error", - detail: Some(err.to_string()), - }) - } -} - -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 -} diff --git a/src/rustc_serialize/writer.rs b/src/rustc_serialize/writer.rs deleted file mode 100644 index cb50a88..0000000 --- a/src/rustc_serialize/writer.rs +++ /dev/null @@ -1,429 +0,0 @@ -use std::io::Write; -use std::io::Error as IoError; -use std::io::ErrorKind as IoErrorKind; -use std::error::Error; -use std::fmt; - -use rustc_serialize_crate::Encoder; - -use byteorder::{BigEndian, WriteBytesExt}; -use byteorder::Error as ByteOrderError; - -pub type EncodingResult = Result; - - -/// An error that can be produced during encoding. -#[derive(Debug)] -pub enum EncodingError { - /// An error originating from the underlying `Writer`. - IoError(IoError), - /// An object could not be encoded with the given size limit. - /// - /// This error is returned before any bytes are written to the - /// output `Writer`. - SizeLimit, -} - -/// An Encoder that encodes values directly into a Writer. -/// -/// This struct should not be used often. -/// For most cases, prefer the `encode_into` function. -pub struct EncoderWriter<'a, W: 'a> { - writer: &'a mut W, -} - -pub struct SizeChecker { - pub size_limit: u64, - pub written: u64 -} - -fn wrap_io(err: ByteOrderError) -> EncodingError { - match err { - ByteOrderError::Io(ioe) => EncodingError::IoError(ioe), - ByteOrderError::UnexpectedEOF => EncodingError::IoError( - IoError::new(IoErrorKind::Other, - "ByteOrder could not write to the buffer")) - } -} - -impl fmt::Display for EncodingError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - EncodingError::IoError(ref err) => write!(f, "IoError: {}", err), - EncodingError::SizeLimit => write!(f, "SizeLimit") - } - } -} - -impl Error for EncodingError { - fn description(&self) -> &str { - match *self { - EncodingError::IoError(ref err) => Error::description(err), - EncodingError::SizeLimit => "the size limit for decoding has been reached" - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - EncodingError::IoError(ref err) => err.cause(), - EncodingError::SizeLimit => None - } - } -} - -impl <'a, W: Write> EncoderWriter<'a, W> { - pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> { - EncoderWriter { - writer: w, - } - } -} - -impl SizeChecker { - pub fn new(limit: u64) -> SizeChecker { - SizeChecker { - size_limit: limit, - written: 0 - } - } - - fn add_raw(&mut self, size: usize) -> EncodingResult<()> { - self.written += size as u64; - if self.written <= self.size_limit { - Ok(()) - } else { - Err(EncodingError::SizeLimit) - } - } - - fn add_value(&mut self, t: T) -> EncodingResult<()> { - use std::mem::size_of_val; - self.add_raw(size_of_val(&t)) - } -} - -impl<'a, W: Write> Encoder for EncoderWriter<'a, W> { - type Error = EncodingError; - - fn emit_nil(&mut self) -> EncodingResult<()> { - Ok(()) - } - fn emit_usize(&mut self, v: usize) -> EncodingResult<()> { - self.emit_u64(v as u64) - } - fn emit_u64(&mut self, v: u64) -> EncodingResult<()> { - self.writer.write_u64::(v).map_err(wrap_io) - } - fn emit_u32(&mut self, v: u32) -> EncodingResult<()> { - self.writer.write_u32::(v).map_err(wrap_io) - } - fn emit_u16(&mut self, v: u16) -> EncodingResult<()> { - self.writer.write_u16::(v).map_err(wrap_io) - } - fn emit_u8(&mut self, v: u8) -> EncodingResult<()> { - self.writer.write_u8(v).map_err(wrap_io) - } - fn emit_isize(&mut self, v: isize) -> EncodingResult<()> { - self.emit_i64(v as i64) - } - fn emit_i64(&mut self, v: i64) -> EncodingResult<()> { - self.writer.write_i64::(v).map_err(wrap_io) - } - fn emit_i32(&mut self, v: i32) -> EncodingResult<()> { - self.writer.write_i32::(v).map_err(wrap_io) - } - fn emit_i16(&mut self, v: i16) -> EncodingResult<()> { - self.writer.write_i16::(v).map_err(wrap_io) - } - fn emit_i8(&mut self, v: i8) -> EncodingResult<()> { - self.writer.write_i8(v).map_err(wrap_io) - } - fn emit_bool(&mut self, v: bool) -> EncodingResult<()> { - self.writer.write_u8(if v {1} else {0}).map_err(wrap_io) - } - fn emit_f64(&mut self, v: f64) -> EncodingResult<()> { - self.writer.write_f64::(v).map_err(wrap_io) - } - fn emit_f32(&mut self, v: f32) -> EncodingResult<()> { - self.writer.write_f32::(v).map_err(wrap_io) - } - fn emit_char(&mut self, v: char) -> EncodingResult<()> { - // TODO: change this back once unicode works - //let mut cbuf = [0; 4]; - //let sz = v.encode_utf8(&mut cbuf[..]).unwrap_or(0); - //let ptr = &cbuf[..sz]; - //self.writer.write_all(ptr).map_err(EncodingError::IoError) - - let mut inter = String::with_capacity(1); - inter.push(v); - self.writer.write_all(inter.as_bytes()).map_err(EncodingError::IoError) - } - fn emit_str(&mut self, v: &str) -> EncodingResult<()> { - try!(self.emit_usize(v.len())); - self.writer.write_all(v.as_bytes()).map_err(EncodingError::IoError) - } - fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - let max_u32: u32 = ::std::u32::MAX; - if v_id > (max_u32 as usize) { - panic!("Variant tag doesn't fit in a u32") - } - try!(self.emit_u32(v_id as u32)); - f(self) - } - fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_struct_variant(&mut self, - _: &str, - _: usize, - _: usize, - f: F) - -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_struct_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple_arg(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - self.emit_tuple(len, f) - } - fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - self.emit_tuple_arg(f_idx, f) - } - fn emit_option(&mut self, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_option_none(&mut self) -> EncodingResult<()> { - self.writer.write_u8(0).map_err(wrap_io) - } - fn emit_option_some(&mut self, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - try!(self.writer.write_u8(1).map_err(wrap_io)); - f(self) - } - fn emit_seq(&mut self, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - try!(self.emit_usize(len)); - f(self) - } - fn emit_seq_elt(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_map(&mut self, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - try!(self.emit_usize(len)); - f(self) - } - fn emit_map_elt_key(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - fn emit_map_elt_val(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - f(self) - } - -} - -impl Encoder for SizeChecker { - type Error = EncodingError; - - fn emit_nil(&mut self) -> EncodingResult<()> { - Ok(()) - } - fn emit_usize(&mut self, v: usize) -> EncodingResult<()> { - self.add_value(v as u64) - } - fn emit_u64(&mut self, v: u64) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_u32(&mut self, v: u32) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_u16(&mut self, v: u16) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_u8(&mut self, v: u8) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_isize(&mut self, v: isize) -> EncodingResult<()> { - self.add_value(v as i64) - } - fn emit_i64(&mut self, v: i64) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_i32(&mut self, v: i32) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_i16(&mut self, v: i16) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_i8(&mut self, v: i8) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_bool(&mut self, _: bool) -> EncodingResult<()> { - self.add_value(0 as u8) - } - fn emit_f64(&mut self, v: f64) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_f32(&mut self, v: f32) -> EncodingResult<()> { - self.add_value(v) - } - fn emit_char(&mut self, v: char) -> EncodingResult<()> { - self.add_raw(v.len_utf8()) - } - fn emit_str(&mut self, v: &str) -> EncodingResult<()> { - try!(self.add_value(0 as u64)); - self.add_raw(v.len()) - } - fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - try!(self.add_value(v_id as u32)); - f(self) - } - fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_struct_variant(&mut self, - _: &str, - _: usize, - _: usize, - f: F) - -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_struct_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple_arg(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - self.emit_tuple(len, f) - } - fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - self.emit_tuple_arg(f_idx, f) - } - fn emit_option(&mut self, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_option_none(&mut self) -> EncodingResult<()> { - self.add_value(0 as u8) - } - fn emit_option_some(&mut self, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - try!(self.add_value(1 as u8)); - f(self) - } - fn emit_seq(&mut self, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - try!(self.emit_usize(len)); - f(self) - } - fn emit_seq_elt(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_map(&mut self, len: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - try!(self.emit_usize(len)); - f(self) - } - fn emit_map_elt_key(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - fn emit_map_elt_val(&mut self, _: usize, f: F) -> EncodingResult<()> - where F: FnOnce(&mut SizeChecker) -> EncodingResult<()> - { - f(self) - } - -} diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 76f648a..9caeb0a 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -1,20 +1,19 @@ //! A collection of serialization and deserialization functions -//! that use the `serde` crate for the serialazble and deserializable +//! that use the `serde` crate for the serializable and deserializable //! implementation. use std::io::{Write, Read}; +use std::io::Error as IoError; +use std::{error, fmt, result}; use ::SizeLimit; +use byteorder::{ByteOrder}; pub use self::reader::{ Deserializer, - DeserializeResult, - DeserializeError, }; pub use self::writer::{ Serializer, - SerializeResult, - SerializeError, }; use self::writer::SizeChecker; @@ -24,16 +23,104 @@ use serde_crate as serde; mod reader; mod writer; +pub type Result = result::Result; + +/// An error that can be produced during (de)serializing. +/// +/// If decoding from a Buffer, assume that the buffer has been left +/// in an invalid state. +pub type Error = Box; + +#[derive(Debug)] +pub enum ErrorKind { + /// If the error stems from the reader/writer that is being used + /// during (de)serialization, 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{ + desc: &'static str, + detail: Option + }, + /// If (de)serializing a message takes more than the provided size limit, this + /// error is returned. + SizeLimit, + SequenceMustHaveLength, + Custom(String) +} + +impl error::Error for ErrorKind { + fn description(&self) -> &str { + match *self { + ErrorKind::IoError(ref err) => error::Error::description(err), + ErrorKind::InvalidEncoding{desc, ..} => desc, + ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences", + ErrorKind::SizeLimit => "the size limit for decoding has been reached", + ErrorKind::Custom(ref msg) => msg, + + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + ErrorKind::IoError(ref err) => err.cause(), + ErrorKind::InvalidEncoding{..} => None, + ErrorKind::SequenceMustHaveLength => None, + ErrorKind::SizeLimit => None, + ErrorKind::Custom(_) => None, + } + } +} + +impl From for Error { + fn from(err: IoError) -> Error { + ErrorKind::IoError(err).into() + } +} + +impl fmt::Display for ErrorKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + ErrorKind::IoError(ref ioerr) => + write!(fmt, "IoError: {}", ioerr), + ErrorKind::InvalidEncoding{desc, detail: None}=> + write!(fmt, "InvalidEncoding: {}", desc), + ErrorKind::InvalidEncoding{desc, detail: Some(ref detail)}=> + write!(fmt, "InvalidEncoding: {} ({})", desc, detail), + ErrorKind::SequenceMustHaveLength => + write!(fmt, "Bincode can only encode sequences and maps that have a knowable size ahead of time."), + ErrorKind::SizeLimit => + write!(fmt, "SizeLimit"), + ErrorKind::Custom(ref s) => + s.fmt(fmt), + } + } +} + +impl serde::de::Error for Error { + fn custom(desc: T) -> Error { + ErrorKind::Custom(desc.to_string()).into() + } +} + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + ErrorKind::Custom(msg.to_string()).into() + } +} + /// Serializes an object directly into a `Writer`. /// /// If the serialization would take more bytes than allowed by `size_limit`, an error /// is returned and *no bytes* will be written into the `Writer`. /// -/// If this returns an `SerializeError` (other than SizeLimit), assume that the +/// If this returns an `Error` (other than SizeLimit), assume that the /// writer is in an invalid state, as writing could bail out in the middle of /// serializing. -pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> SerializeResult<()> - where W: Write, T: serde::Serialize, +pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> Result<()> + where W: Write, T: serde::Serialize, E: ByteOrder { match size_limit { SizeLimit::Infinite => { } @@ -43,7 +130,7 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> } } - let mut serializer = Serializer::new(writer); + let mut serializer = Serializer::<_, E>::new(writer); serde::Serialize::serialize(value, &mut serializer) } @@ -51,24 +138,21 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> /// /// If the serialization would take more bytes than allowed by `size_limit`, /// an error is returned. -pub fn serialize(value: &T, size_limit: SizeLimit) -> SerializeResult> - where T: serde::Serialize, +pub fn serialize(value: &T, size_limit: SizeLimit) -> Result> + where T: serde::Serialize { // Since we are putting values directly into a vector, we can do size // computation out here and pre-allocate a buffer of *exactly* // the right size. let mut writer = match size_limit { SizeLimit::Bounded(size_limit) => { - let actual_size = match serialized_size_bounded(value, size_limit) { - Some(actual_size) => actual_size, - None => { return Err(SerializeError::SizeLimit); } - }; + let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(ErrorKind::SizeLimit)); Vec::with_capacity(actual_size as usize) } SizeLimit::Infinite => Vec::new() }; - try!(serialize_into(&mut writer, value, SizeLimit::Infinite)); + try!(serialize_into::<_, _, E>(&mut writer, value, SizeLimit::Infinite)); Ok(writer) } @@ -76,7 +160,9 @@ pub fn serialize(value: &T, size_limit: SizeLimit) -> SerializeResult /// /// This is used internally as part of the check for encode_into, but it can /// be useful for preallocating buffers if thats your style. -pub fn serialized_size(value: &T) -> u64 { +pub fn serialized_size(value: &T) -> u64 + where T: serde::Serialize +{ use std::u64::MAX; let mut size_checker = SizeChecker::new(MAX); value.serialize(&mut size_checker).ok(); @@ -88,7 +174,9 @@ pub fn serialized_size(value: &T) -> u64 { /// /// If it can be serialized in `max` or fewer bytes, that number will be returned /// inside `Some`. If it goes over bounds, then None is returned. -pub fn serialized_size_bounded(value: &T, max: u64) -> Option { +pub fn serialized_size_bounded(value: &T, max: u64) -> Option + where T: serde::Serialize +{ let mut size_checker = SizeChecker::new(max); value.serialize(&mut size_checker).ok().map(|_| size_checker.written) } @@ -99,14 +187,14 @@ pub fn serialized_size_bounded(value: &T, max: u64) -> Opti /// A SizeLimit can help prevent an attacker from flooding your server with /// a neverending stream of values that runs your server out of memory. /// -/// If this returns an `DeserializeError`, assume that the buffer that you passed +/// If this returns an `Error`, assume that the buffer that you passed /// in is in an invalid state, as the error could be returned during any point /// in the reading. -pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> DeserializeResult +pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> Result where R: Read, T: serde::Deserialize, { - let mut deserializer = Deserializer::new(reader, size_limit); + let mut deserializer = Deserializer::<_, E>::new(reader, size_limit); serde::Deserialize::deserialize(&mut deserializer) } @@ -114,10 +202,9 @@ pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> Deserial /// /// This method does not have a size-limit because if you already have the bytes /// in memory, then you don't gain anything by having a limiter. -pub fn deserialize(bytes: &[u8]) -> DeserializeResult +pub fn deserialize(bytes: &[u8]) -> Result where T: serde::Deserialize, { let mut reader = bytes; - deserialize_from(&mut reader, SizeLimit::Infinite) + deserialize_from::<_, _, E>(&mut reader, SizeLimit::Infinite) } - diff --git a/src/serde/reader.rs b/src/serde/reader.rs index f0a957c..8d6e2db 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -1,125 +1,12 @@ use std::io::Read; -use std::io::Error as IoError; -use std::error::Error; -use std::fmt; -use std::convert::From; +use std::marker::PhantomData; -use byteorder::Error as ByteOrderError; -use byteorder::{BigEndian, ReadBytesExt}; -use num; +use byteorder::{ReadBytesExt, ByteOrder}; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; -use serde_crate::de::Deserializer as SerdeDeserializer; - +use serde_crate::de::Error as DeError; use ::SizeLimit; - -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct InvalidEncoding { - desc: &'static str, - detail: Option, -} - -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, - Serde(serde::de::value::Error) -} - -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::Serde(ref s) => s.description(), - - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - DeserializeError::IoError(ref err) => err.cause(), - DeserializeError::InvalidEncoding(_) => None, - DeserializeError::SizeLimit => None, - DeserializeError::Serde(ref s) => s.cause(), - } - } -} - -impl From for DeserializeError { - fn from(err: IoError) -> DeserializeError { - DeserializeError::IoError(err) - } -} - -impl From for DeserializeError { - fn from(err: ByteOrderError) -> DeserializeError { - match err { - ByteOrderError::Io(ioe) => DeserializeError::IoError(ioe), - ByteOrderError::UnexpectedEOF => DeserializeError::Serde( - serde::de::value::Error::EndOfStream), - } - } -} - -impl From for DeserializeError { - fn from(err: serde::de::value::Error) -> DeserializeError { - DeserializeError::Serde(err) - } -} - -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::Serde(ref s) => - s.fmt(fmt), - } - } -} - -impl serde::de::Error for DeserializeError { - fn custom>(desc: T) -> DeserializeError { - DeserializeError::Serde(serde::de::value::Error::Custom(desc.into())) - } - - fn end_of_stream() -> DeserializeError { - DeserializeError::Serde(serde::de::value::Error::EndOfStream) - } -} - -pub type DeserializeResult = Result; - +use super::{Result, Error, ErrorKind}; /// A Deserializer that reads bytes from a buffer. /// @@ -131,18 +18,20 @@ pub type DeserializeResult = Result; /// serde::Deserialize::deserialize(&mut deserializer); /// let bytes_read = d.bytes_read(); /// ``` -pub struct Deserializer<'a, R: 'a> { - reader: &'a mut R, +pub struct Deserializer { + reader: R, size_limit: SizeLimit, - read: u64 + read: u64, + _phantom: PhantomData, } -impl<'a, R: Read> Deserializer<'a, R> { - pub fn new(r: &'a mut R, size_limit: SizeLimit) -> Deserializer<'a, R> { +impl Deserializer { + pub fn new(r: R, size_limit: SizeLimit) -> Deserializer { Deserializer { reader: r, size_limit: size_limit, - read: 0 + read: 0, + _phantom: PhantomData } } @@ -150,50 +39,66 @@ impl<'a, R: Read> Deserializer<'a, R> { pub fn bytes_read(&self) -> u64 { self.read } -} -impl <'a, A> Deserializer<'a, A> { - fn read_bytes(&mut self, count: u64) -> Result<(), DeserializeError> { + fn read_bytes(&mut self, count: u64) -> Result<()> { self.read += count; match self.size_limit { SizeLimit::Infinite => Ok(()), SizeLimit::Bounded(x) if self.read <= x => Ok(()), - SizeLimit::Bounded(_) => Err(DeserializeError::SizeLimit) + SizeLimit::Bounded(_) => Err(ErrorKind::SizeLimit.into()) } } - fn read_type(&mut self) -> Result<(), DeserializeError> { + fn read_type(&mut self) -> Result<()> { use std::mem::size_of; self.read_bytes(size_of::() as u64) } + + fn read_vec(&mut self) -> Result> { + let len = try!(serde::Deserialize::deserialize(&mut *self)); + try!(self.read_bytes(len)); + + let len = len as usize; + let mut bytes = Vec::with_capacity(len); + unsafe { bytes.set_len(len); } + try!(self.reader.read_exact(&mut bytes)); + Ok(bytes) + } + + fn read_string(&mut self) -> Result { + String::from_utf8(try!(self.read_vec())).map_err(|err| + ErrorKind::InvalidEncoding{ + desc: "error while decoding utf8 string", + detail: Some(format!("Deserialize error: {}", err)) + }.into()) + } } macro_rules! impl_nums { ($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => { #[inline] - fn $dser_method(&mut self, mut visitor: V) -> DeserializeResult + fn $dser_method(self, visitor: V) -> Result where V: serde::de::Visitor, { try!(self.read_type::<$ty>()); - let value = try!(self.reader.$reader_method::()); + let value = try!(self.reader.$reader_method::()); visitor.$visitor_method(value) } } } - -impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { - type Error = DeserializeError; +impl<'a, R: Read, E: ByteOrder> serde::Deserializer for &'a mut Deserializer { + type Error = Error; #[inline] - fn deserialize(&mut self, _visitor: V) -> DeserializeResult + fn deserialize(self, _visitor: V) -> Result where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize"; - Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + Err(Error::custom(message)) } - fn deserialize_bool(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_bool(self, visitor: V) -> Result where V: serde::de::Visitor, { let value: u8 = try!(serde::Deserialize::deserialize(self)); @@ -201,10 +106,10 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { 1 => visitor.visit_bool(true), 0 => visitor.visit_bool(false), value => { - Err(DeserializeError::InvalidEncoding(InvalidEncoding { + Err(ErrorKind::InvalidEncoding{ desc: "invalid u8 when decoding bool", detail: Some(format!("Expected 0 or 1, got {}", value)) - })) + }.into()) } } } @@ -220,7 +125,7 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { #[inline] - fn deserialize_u8(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_u8(self, visitor: V) -> Result where V: serde::de::Visitor, { try!(self.read_type::()); @@ -228,52 +133,28 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { } #[inline] - fn deserialize_usize(&mut self, mut visitor: V) -> DeserializeResult - where V: serde::de::Visitor, - { - try!(self.read_type::()); - let value = try!(self.reader.read_u64::()); - match num::cast(value) { - Some(value) => visitor.visit_usize(value), - None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected usize".into()))) - } - } - - #[inline] - fn deserialize_i8(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_i8(self, visitor: V) -> Result where V: serde::de::Visitor, { try!(self.read_type::()); visitor.visit_i8(try!(self.reader.read_i8())) } - #[inline] - fn deserialize_isize(&mut self, mut visitor: V) -> DeserializeResult - where V: serde::de::Visitor, - { - try!(self.read_type::()); - let value = try!(self.reader.read_i64::()); - match num::cast(value) { - Some(value) => visitor.visit_isize(value), - None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected isize".into()))), - } - } - - fn deserialize_unit(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_unit(self, visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_unit() } - fn deserialize_char(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_char(self, visitor: V) -> Result where V: serde::de::Visitor, { use std::str; - let error = DeserializeError::InvalidEncoding(InvalidEncoding { + let error = ErrorKind::InvalidEncoding{ desc: "Invalid char encoding", detail: None - }); + }.into(); let mut buf = [0]; @@ -300,208 +181,238 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { None => Err(error) }); - try!(self.read_bytes(res.len_utf8() as u64)); visitor.visit_char(res) } - fn deserialize_string(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_str(self, visitor: V) -> Result 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)) - })), - } + visitor.visit_str(&try!(self.read_string())) } - fn deserialize_enum(&mut self, + fn deserialize_string(self, visitor: V) -> Result + where V: serde::de::Visitor, + { + visitor.visit_string(try!(self.read_string())) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where V: serde::de::Visitor, + { + visitor.visit_bytes(&try!(self.read_vec())) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where V: serde::de::Visitor, + { + visitor.visit_byte_buf(try!(self.read_vec())) + } + + fn deserialize_enum(self, _enum: &'static str, _variants: &'static [&'static str], - mut visitor: V) -> Result - where V: serde::de::EnumVisitor, - { - visitor.visit(self) - } - - fn deserialize_tuple(&mut self, - _len: usize, - mut visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { - struct TupleVisitor<'a, 'b: 'a, R: Read + 'b>(&'a mut Deserializer<'b, R>); + impl<'a, R: Read + 'a, E: ByteOrder> serde::de::EnumVisitor for &'a mut Deserializer { + type Error = Error; + type Variant = Self; - impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, 'b, R> { - type Error = DeserializeError; - - fn visit(&mut self) -> Result, Self::Error> - where T: serde::de::Deserialize, + fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> + where V: serde::de::DeserializeSeed, { - let value = try!(serde::Deserialize::deserialize(self.0)); - Ok(Some(value)) + let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self)); + let val: Result<_> = seed.deserialize(idx.into_deserializer()); + Ok((try!(val), self)) } + } - fn end(&mut self) -> Result<(), Self::Error> { - Ok(()) + visitor.visit_enum(self) + } + + fn deserialize_tuple(self, + _len: usize, + visitor: V) -> Result + where V: serde::de::Visitor, + { + struct TupleVisitor<'a, R: Read + 'a, E: ByteOrder + 'a>(&'a mut Deserializer); + + impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::SeqVisitor for TupleVisitor<'a, R, E> { + type Error = Error; + + fn visit_seed(&mut self, seed: T) -> Result> + where T: serde::de::DeserializeSeed, + { + let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.0)); + Ok(Some(value)) } } visitor.visit_seq(TupleVisitor(self)) } - fn deserialize_option(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_seq_fixed_size(self, + len: usize, + visitor: V) -> Result 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 deserialize_seq(&mut self, mut visitor: V) -> DeserializeResult - where V: serde::de::Visitor, - { - struct SeqVisitor<'a, 'b: 'a, R: Read + 'b> { - deserializer: &'a mut Deserializer<'b, R>, + struct SeqVisitor<'a, R: Read + 'a, E: ByteOrder + 'a> { + deserializer: &'a mut Deserializer, len: usize, } - impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, 'b, R> { - type Error = DeserializeError; + impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::SeqVisitor for SeqVisitor<'a, R, E> { + type Error = Error; - fn visit(&mut self) -> Result, Self::Error> - where T: serde::de::Deserialize, + fn visit_seed(&mut self, seed: T) -> Result> + where T: serde::de::DeserializeSeed, { if self.len > 0 { self.len -= 1; - let value = try!(serde::Deserialize::deserialize(self.deserializer)); + let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)); Ok(Some(value)) } else { Ok(None) } } - - fn end(&mut self) -> Result<(), Self::Error> { - if self.len == 0 { - Ok(()) - } else { - Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected end".into()))) - } - } } - let len = try!(serde::Deserialize::deserialize(self)); - visitor.visit_seq(SeqVisitor { deserializer: self, len: len }) } - fn deserialize_map(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor, { - struct MapVisitor<'a, 'b: 'a, R: Read + 'b> { - deserializer: &'a mut Deserializer<'b, R>, + let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); + match value { + 0 => visitor.visit_none(), + 1 => visitor.visit_some(&mut *self), + _ => Err(ErrorKind::InvalidEncoding{ + desc: "invalid tag when decoding Option", + detail: Some(format!("Expected 0 or 1, got {}", value)) + }.into()), + } + } + + fn deserialize_seq(self, visitor: V) -> Result + where V: serde::de::Visitor, + { + let len = try!(serde::Deserialize::deserialize(&mut *self)); + + self.deserialize_seq_fixed_size(len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where V: serde::de::Visitor, + { + struct MapVisitor<'a, R: Read + 'a, E: ByteOrder + 'a> { + deserializer: &'a mut Deserializer, len: usize, } - impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, 'b, R> { - type Error = DeserializeError; + impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::MapVisitor for MapVisitor<'a, R, E> { + type Error = Error; - fn visit_key(&mut self) -> Result, Self::Error> - where K: serde::de::Deserialize, + fn visit_key_seed(&mut self, seed: K) -> Result> + where K: serde::de::DeserializeSeed, { if self.len > 0 { self.len -= 1; - let key = try!(serde::Deserialize::deserialize(self.deserializer)); + let key = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)); Ok(Some(key)) } else { Ok(None) } } - fn visit_value(&mut self) -> Result - where V: serde::de::Deserialize, + fn visit_value_seed(&mut self, seed: V) -> Result + where V: serde::de::DeserializeSeed, { - let value = try!(serde::Deserialize::deserialize(self.deserializer)); + let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)); Ok(value) } - - fn end(&mut self) -> Result<(), Self::Error> { - if self.len == 0 { - Ok(()) - } else { - Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected end".into()))) - } - } } - let len = try!(serde::Deserialize::deserialize(self)); + let len = try!(serde::Deserialize::deserialize(&mut *self)); visitor.visit_map(MapVisitor { deserializer: self, len: len }) } - fn deserialize_struct(&mut self, + fn deserialize_struct(self, _name: &str, fields: &'static [&'static str], - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { self.deserialize_tuple(fields.len(), visitor) } - fn deserialize_newtype_struct(&mut self, + fn deserialize_struct_field(self, + _visitor: V) -> Result + where V: serde::de::Visitor, + { + let message = "bincode does not support Deserializer::deserialize_struct_field"; + Err(Error::custom(message)) + } + + fn deserialize_newtype_struct(self, _name: &str, - mut visitor: V) -> Result + visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_newtype_struct(self) } -} -impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> { - type Error = DeserializeError; - - fn visit_variant(&mut self) -> Result - where V: serde::Deserialize, + fn deserialize_unit_struct(self, + _name: &'static str, + visitor: V) -> Result + where V: serde::de::Visitor, { - let index: u32 = try!(serde::Deserialize::deserialize(self)); - let mut deserializer = (index as usize).into_deserializer(); - let attempt: Result = serde::Deserialize::deserialize(&mut deserializer); - Ok(try!(attempt)) + visitor.visit_unit() } - fn visit_unit(&mut self) -> Result<(), Self::Error> { + fn deserialize_tuple_struct(self, + _name: &'static str, + len: usize, + visitor: V) -> Result + where V: serde::de::Visitor, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_ignored_any(self, + _visitor: V) -> Result + where V: serde::de::Visitor, + { + let message = "bincode does not support Deserializer::deserialize_ignored_any"; + Err(Error::custom(message)) + } +} + +impl<'a, R: Read, E: ByteOrder> serde::de::VariantVisitor for &'a mut Deserializer { + type Error = Error; + + fn visit_unit(self) -> Result<()> { Ok(()) } - fn visit_newtype(&mut self) -> Result - where T: serde::de::Deserialize, + fn visit_newtype_seed(self, seed: T) -> Result + where T: serde::de::DeserializeSeed, { - serde::de::Deserialize::deserialize(self) + serde::de::DeserializeSeed::deserialize(seed, self) } - fn visit_tuple(&mut self, + fn visit_tuple(self, len: usize, - visitor: V) -> Result + visitor: V) -> Result where V: serde::de::Visitor, { serde::de::Deserializer::deserialize_tuple(self, len, visitor) } - fn visit_struct(&mut self, + fn visit_struct(self, fields: &'static [&'static str], - visitor: V) -> Result + visitor: V) -> Result where V: serde::de::Visitor, { serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor) diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 3f8e71b..3bb10fc 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -1,91 +1,31 @@ -use std::error::Error; -use std::fmt; -use std::io::Error as IoError; -use std::io::ErrorKind as IoErrorKind; use std::io::Write; use std::u32; +use std::marker::PhantomData; use serde_crate as serde; -use byteorder::{BigEndian, WriteBytesExt}; -use byteorder::Error as ByteOrderError; +use byteorder::{WriteBytesExt, ByteOrder}; -pub type SerializeResult = Result; - - -/// An error that can be produced during encoding. -#[derive(Debug)] -pub enum SerializeError { - /// An error originating from the underlying `Writer`. - IoError(IoError), - /// An object could not be encoded with the given size limit. - /// - /// This error is returned before any bytes are written to the - /// output `Writer`. - SizeLimit, - /// A custom error message - Custom(String) -} +use super::{Result, Error, ErrorKind}; /// An Serializer that encodes values directly into a Writer. /// /// This struct should not be used often. /// For most cases, prefer the `encode_into` function. -pub struct Serializer<'a, W: 'a> { - writer: &'a mut W, +pub struct Serializer { + writer: W, + _phantom: PhantomData, } -fn wrap_io(err: ByteOrderError) -> SerializeError { - match err { - ByteOrderError::Io(ioe) => SerializeError::IoError(ioe), - ByteOrderError::UnexpectedEOF => SerializeError::IoError( - IoError::new(IoErrorKind::Other, - "ByteOrder could not write to the buffer")) - } -} - -impl serde::ser::Error for SerializeError { - fn custom>(msg: T) -> Self { - SerializeError::Custom(msg.into()) - } -} - -impl fmt::Display for SerializeError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - SerializeError::IoError(ref err) => write!(f, "IoError: {}", err), - SerializeError::Custom(ref s) => write!(f, "Custom Error {}", s), - SerializeError::SizeLimit => write!(f, "SizeLimit"), - } - } -} - -impl Error for SerializeError { - fn description(&self) -> &str { - match *self { - SerializeError::IoError(ref err) => Error::description(err), - SerializeError::SizeLimit => "the size limit for decoding has been reached", - SerializeError::Custom(_) => "a custom serialization error was reported", - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - SerializeError::IoError(ref err) => err.cause(), - SerializeError::SizeLimit => None, - SerializeError::Custom(_) => None, - } - } -} - -impl<'a, W: Write> Serializer<'a, W> { - pub fn new(w: &'a mut W) -> Serializer<'a, W> { +impl Serializer { + pub fn new(w: W) -> Serializer { Serializer { writer: w, + _phantom: PhantomData, } } - fn add_enum_tag(&mut self, tag: usize) -> SerializeResult<()> { + fn add_enum_tag(&mut self, tag: usize) -> Result<()> { if tag > u32::MAX as usize { panic!("Variant tag doesn't fit in a u32") } @@ -94,178 +34,162 @@ impl<'a, W: Write> Serializer<'a, W> { } } -impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { - type Error = SerializeError; +impl<'a, W: Write, E: ByteOrder> serde::Serializer for &'a mut Serializer { + type Ok = (); + type Error = Error; + type SerializeSeq = Compound<'a, W, E>; + type SerializeTuple = Compound<'a, W, E>; + type SerializeTupleStruct = Compound<'a, W, E>; + type SerializeTupleVariant = Compound<'a, W, E>; + type SerializeMap = Compound<'a, W, E>; + type SerializeStruct = Compound<'a, W, E>; + type SerializeStructVariant = Compound<'a, W, E>; - fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit(self) -> Result<()> { Ok(()) } - fn serialize_bool(&mut self, v: bool) -> SerializeResult<()> { - self.writer.write_u8(if v {1} else {0}).map_err(wrap_io) + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) } + + fn serialize_bool(self, v: bool) -> Result<()> { + self.writer.write_u8(if v {1} else {0}).map_err(Into::into) } - fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> { - self.writer.write_u8(v).map_err(wrap_io) + fn serialize_u8(self, v: u8) -> Result<()> { + self.writer.write_u8(v).map_err(Into::into) } - fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> { - self.writer.write_u16::(v).map_err(wrap_io) + fn serialize_u16(self, v: u16) -> Result<()> { + self.writer.write_u16::(v).map_err(Into::into) } - fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> { - self.writer.write_u32::(v).map_err(wrap_io) + fn serialize_u32(self, v: u32) -> Result<()> { + self.writer.write_u32::(v).map_err(Into::into) } - fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> { - self.writer.write_u64::(v).map_err(wrap_io) + fn serialize_u64(self, v: u64) -> Result<()> { + self.writer.write_u64::(v).map_err(Into::into) } - fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { - self.writer.write_i8(v).map_err(wrap_io) + fn serialize_i8(self, v: i8) -> Result<()> { + self.writer.write_i8(v).map_err(Into::into) } - fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> { - self.writer.write_i16::(v).map_err(wrap_io) + fn serialize_i16(self, v: i16) -> Result<()> { + self.writer.write_i16::(v).map_err(Into::into) } - fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> { - self.writer.write_i32::(v).map_err(wrap_io) + fn serialize_i32(self, v: i32) -> Result<()> { + self.writer.write_i32::(v).map_err(Into::into) } - fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> { - self.writer.write_i64::(v).map_err(wrap_io) + fn serialize_i64(self, v: i64) -> Result<()> { + self.writer.write_i64::(v).map_err(Into::into) } - fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { - self.writer.write_f32::(v).map_err(wrap_io) + fn serialize_f32(self, v: f32) -> Result<()> { + self.writer.write_f32::(v).map_err(Into::into) } - fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> { - self.writer.write_f64::(v).map_err(wrap_io) + fn serialize_f64(self, v: f64) -> Result<()> { + self.writer.write_f64::(v).map_err(Into::into) } - fn serialize_str(&mut self, v: &str) -> SerializeResult<()> { - try!(self.serialize_usize(v.len())); - self.writer.write_all(v.as_bytes()).map_err(SerializeError::IoError) + fn serialize_str(self, v: &str) -> Result<()> { + try!(self.serialize_u64(v.len() as u64)); + self.writer.write_all(v.as_bytes()).map_err(Into::into) } - fn serialize_none(&mut self) -> SerializeResult<()> { - self.writer.write_u8(0).map_err(wrap_io) + fn serialize_char(self, c: char) -> Result<()> { + self.writer.write_all(encode_utf8(c).as_slice()).map_err(Into::into) } - fn serialize_some(&mut self, v: T) -> SerializeResult<()> + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + try!(self.serialize_u64(v.len() as u64)); + self.writer.write_all(v).map_err(Into::into) + } + + fn serialize_none(self) -> Result<()> { + self.writer.write_u8(0).map_err(Into::into) + } + + fn serialize_some(self, v: &T) -> Result<()> where T: serde::Serialize, { - try!(self.writer.write_u8(1).map_err(wrap_io)); + try!(self.writer.write_u8(1)); v.serialize(self) } - fn serialize_seq(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, - { - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a sequence with no length"), - }; - - try!(self.serialize_usize(len)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_seq(self, len: Option) -> Result { + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); + try!(self.serialize_u64(len as u64)); + Ok(Compound {ser: self}) } - fn serialize_tuple(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, - { - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_seq_fixed_size(self, _len: usize) -> Result { + Ok(Compound {ser: self}) } - fn serialize_seq_elt(&mut self, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_tuple(self, _len: usize) -> Result { + Ok(Compound {ser: self}) } - fn serialize_map(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, - { - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a map with no length"), - }; - - try!(self.serialize_usize(len)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(Compound {ser: self}) } - fn serialize_map_elt(&mut self, key: K, value: V) -> SerializeResult<()> - where K: serde::Serialize, - V: serde::Serialize, + fn serialize_tuple_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> Result { - try!(key.serialize(self)); - value.serialize(self) + try!(self.add_enum_tag(variant_index)); + Ok(Compound {ser: self}) } - fn serialize_struct(&mut self, _name: &str, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, - { - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_map(self, len: Option) -> Result { + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); + try!(self.serialize_u64(len as u64)); + Ok(Compound {ser: self}) } - fn serialize_struct_elt(&mut self, _key: &str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(Compound {ser: self}) } - fn serialize_newtype_struct(&mut self, - _name: &str, - value: T) -> SerializeResult<()> + fn serialize_struct_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> Result + { + try!(self.add_enum_tag(variant_index)); + Ok(Compound {ser: self}) + } + + fn serialize_newtype_struct(self, + _name: &'static str, + value: &T) -> Result<()> where T: serde::ser::Serialize, { value.serialize(self) } - fn serialize_unit_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str) -> SerializeResult<()> { - self.add_enum_tag(variant_index) - } - - fn serialize_tuple_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, - { - try!(self.add_enum_tag(variant_index)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) - } - - fn serialize_struct_variant(&mut self, - _name: &str, + fn serialize_newtype_variant(self, + _name: &'static str, variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, + _variant: &'static str, + value: &T) -> Result<()> + where T: serde::ser::Serialize, { try!(self.add_enum_tag(variant_index)); + value.serialize(self) + } - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_unit_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str) -> Result<()> { + self.add_enum_tag(variant_index) } } @@ -282,21 +206,21 @@ impl SizeChecker { } } - fn add_raw(&mut self, size: usize) -> SerializeResult<()> { + fn add_raw(&mut self, size: usize) -> Result<()> { self.written += size as u64; if self.written <= self.size_limit { Ok(()) } else { - Err(SerializeError::SizeLimit) + Err(ErrorKind::SizeLimit.into()) } } - fn add_value(&mut self, t: T) -> SerializeResult<()> { + fn add_value(&mut self, t: T) -> Result<()> { use std::mem::size_of_val; self.add_raw(size_of_val(&t)) } - fn add_enum_tag(&mut self, tag: usize) -> SerializeResult<()> { + fn add_enum_tag(&mut self, tag: usize) -> Result<()> { if tag > u32::MAX as usize { panic!("Variant tag doesn't fit in a u32") } @@ -305,169 +229,486 @@ impl SizeChecker { } } -impl serde::Serializer for SizeChecker { - type Error = SerializeError; +impl<'a> serde::Serializer for &'a mut SizeChecker { + type Ok = (); + type Error = Error; + type SerializeSeq = SizeCompound<'a>; + type SerializeTuple = SizeCompound<'a>; + type SerializeTupleStruct = SizeCompound<'a>; + type SerializeTupleVariant = SizeCompound<'a>; + type SerializeMap = SizeCompound<'a>; + type SerializeStruct = SizeCompound<'a>; + type SerializeStructVariant = SizeCompound<'a>; - fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit(self) -> Result<()> { Ok(()) } - fn serialize_bool(&mut self, _: bool) -> SerializeResult<()> { + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) } + + fn serialize_bool(self, _: bool) -> Result<()> { self.add_value(0 as u8) } - fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> { + fn serialize_u8(self, v: u8) -> Result<()> { self.add_value(v) } - fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> { + fn serialize_u16(self, v: u16) -> Result<()> { self.add_value(v) } - fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> { + fn serialize_u32(self, v: u32) -> Result<()> { self.add_value(v) } - fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> { + fn serialize_u64(self, v: u64) -> Result<()> { self.add_value(v) } - fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { + fn serialize_i8(self, v: i8) -> Result<()> { self.add_value(v) } - fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> { + fn serialize_i16(self, v: i16) -> Result<()> { self.add_value(v) } - fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> { + fn serialize_i32(self, v: i32) -> Result<()> { self.add_value(v) } - fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> { + fn serialize_i64(self, v: i64) -> Result<()> { self.add_value(v) } - fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { + fn serialize_f32(self, v: f32) -> Result<()> { self.add_value(v) } - fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> { + fn serialize_f64(self, v: f64) -> Result<()> { self.add_value(v) } - fn serialize_str(&mut self, v: &str) -> SerializeResult<()> { + fn serialize_str(self, v: &str) -> Result<()> { try!(self.add_value(0 as u64)); self.add_raw(v.len()) } - fn serialize_none(&mut self) -> SerializeResult<()> { + fn serialize_char(self, c: char) -> Result<()> { + self.add_raw(encode_utf8(c).as_slice().len()) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + try!(self.add_value(0 as u64)); + self.add_raw(v.len()) + } + + fn serialize_none(self) -> Result<()> { self.add_value(0 as u8) } - fn serialize_some(&mut self, v: T) -> SerializeResult<()> + fn serialize_some(self, v: &T) -> Result<()> where T: serde::Serialize, { try!(self.add_value(1 as u8)); v.serialize(self) } - fn serialize_seq(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, - { - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a sequence with no length"), - }; + fn serialize_seq(self, len: Option) -> Result { + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - try!(self.serialize_usize(len)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + try!(self.serialize_u64(len as u64)); + Ok(SizeCompound {ser: self}) } - fn serialize_tuple(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, - { - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_seq_fixed_size(self, _len: usize) -> Result { + Ok(SizeCompound {ser: self}) } - fn serialize_seq_elt(&mut self, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_tuple(self, _len: usize) -> Result { + Ok(SizeCompound {ser: self}) } - fn serialize_map(&mut self, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, - { - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a map with no length"), - }; - - try!(self.serialize_usize(len)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(SizeCompound {ser: self}) } - fn serialize_map_elt(&mut self, key: K, value: V) -> SerializeResult<()> - where K: serde::Serialize, - V: serde::Serialize, + fn serialize_tuple_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> Result { - try!(key.serialize(self)); - value.serialize(self) + try!(self.add_enum_tag(variant_index)); + Ok(SizeCompound {ser: self}) } - fn serialize_struct(&mut self, _name: &str, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, + fn serialize_map(self, len: Option) -> Result { - while let Some(()) = try!(visitor.visit(self)) { } + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - Ok(()) + try!(self.serialize_u64(len as u64)); + Ok(SizeCompound {ser: self}) } - fn serialize_struct_elt(&mut self, _key: &str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(SizeCompound {ser: self}) } - fn serialize_unit_variant(&mut self, - _name: &str, + fn serialize_struct_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> Result + { + try!(self.add_enum_tag(variant_index)); + Ok(SizeCompound {ser: self}) + } + + fn serialize_newtype_struct(self, _name: &'static str, v: &V) -> Result<()> { + v.serialize(self) + } + + fn serialize_unit_variant(self, + _name: &'static str, variant_index: usize, - _variant: &str) -> SerializeResult<()> { + _variant: &'static str) -> Result<()> { self.add_enum_tag(variant_index) } - fn serialize_tuple_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::SeqVisitor, + fn serialize_newtype_variant(self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + value: &V) -> Result<()> { try!(self.add_enum_tag(variant_index)); + value.serialize(self) + } +} - while let Some(()) = try!(visitor.visit(self)) { } +#[doc(hidden)] +pub struct Compound<'a, W: 'a, E: ByteOrder + 'a> { + ser: &'a mut Serializer, +} - Ok(()) +impl<'a, W, E> serde::ser::SerializeSeq for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) } - fn serialize_struct_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, - { - try!(self.add_enum_tag(variant_index)); - - while let Some(()) = try!(visitor.visit(self)) { } - + #[inline] + fn end(self) -> Result<()> { Ok(()) } } + +impl<'a, W, E> serde::ser::SerializeTuple for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, E> serde::ser::SerializeTupleStruct for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, E> serde::ser::SerializeTupleVariant for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, E> serde::ser::SerializeMap for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where K: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where V: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, E> serde::ser::SerializeStruct for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, E> serde::ser::SerializeStructVariant for Compound<'a, W, E> + where W: Write, E: ByteOrder +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +#[doc(hidden)] +pub struct SizeCompound<'a> { + ser: &'a mut SizeChecker, +} + +impl<'a> serde::ser::SerializeSeq for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTuple for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTupleStruct for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTupleVariant for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeMap for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where K: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where V: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeStruct for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeStructVariant for SizeCompound<'a> +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; + +fn encode_utf8(c: char) -> EncodeUtf8 { + let code = c as u32; + let mut buf = [0; 4]; + let pos = if code < MAX_ONE_B { + buf[3] = code as u8; + 3 + } else if code < MAX_TWO_B { + buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 2 + } else if code < MAX_THREE_B { + buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 1 + } else { + buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 0 + }; + EncodeUtf8 { buf: buf, pos: pos } +} + +struct EncodeUtf8 { + buf: [u8; 4], + pos: usize, +} + +impl EncodeUtf8 { + fn as_slice(&self) -> &[u8] { + &self.buf[self.pos..] + } +} diff --git a/tests/test.rs b/tests/test.rs index e2540ea..914013c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,74 +1,61 @@ -#![feature(plugin, custom_derive, custom_attribute)] -#![plugin(serde_macros)] +#[macro_use] +extern crate serde_derive; extern crate bincode; -extern crate rustc_serialize; extern crate serde; +extern crate byteorder; use std::fmt::Debug; use std::collections::HashMap; use std::ops::Deref; -use rustc_serialize::{Encoder, Decoder, Encodable, Decodable}; +use bincode::refbox::{RefBox, StrBox, SliceBox}; -use bincode::{RefBox, StrBox, SliceBox}; +use bincode::SizeLimit::{Infinite, Bounded}; +use bincode::{serialized_size, ErrorKind, Result}; +use bincode::endian_choice::{serialize, deserialize}; -use bincode::SizeLimit::{self, Infinite, Bounded}; -use bincode::rustc_serialize::{encode, decode, decode_from, DecodingError}; -use bincode::serde::{serialize, deserialize, deserialize_from, DeserializeError, DeserializeResult}; - -fn proxy_encode(element: &V, size_limit: SizeLimit) -> Vec - where V: Encodable + Decodable + serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static -{ - let v1 = bincode::rustc_serialize::encode(element, size_limit).unwrap(); - let v2 = bincode::serde::serialize(element, size_limit).unwrap(); - assert_eq!(v1, v2); - - v1 -} - -fn proxy_decode(slice: &[u8]) -> V - where V: Encodable + Decodable + serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static -{ - let e1 = bincode::rustc_serialize::decode(slice).unwrap(); - let e2 = bincode::serde::deserialize(slice).unwrap(); - - assert_eq!(e1, e2); - - e1 -} - -fn proxy_encoded_size(element: &V) -> u64 - where V: Encodable + serde::Serialize + PartialEq + Debug + 'static -{ - let ser_size = bincode::rustc_serialize::encoded_size(element); - let serde_size = bincode::serde::serialized_size(element); - assert_eq!(ser_size, serde_size); - ser_size -} +use bincode::serialize as serialize_little; +use bincode::deserialize as deserialize_little; +use bincode::deserialize_from as deserialize_from_little; fn the_same(element: V) - where V: Encodable+Decodable+serde::Serialize+serde::Deserialize+PartialEq+Debug+'static + where V: serde::Serialize+serde::Deserialize+PartialEq+Debug+'static { // Make sure that the bahavior isize correct when wrapping with a RefBox. fn ref_box_correct(v: &V) -> bool - where V: Encodable + Decodable + PartialEq + Debug + 'static + where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static { let rf = RefBox::new(v); - let encoded = bincode::rustc_serialize::encode(&rf, Infinite).unwrap(); - let decoded: RefBox<'static, V> = bincode::rustc_serialize::decode(&encoded[..]).unwrap(); + let encoded = serialize_little(&rf, Infinite).unwrap(); + let decoded: RefBox<'static, V> = deserialize_little(&encoded[..]).unwrap(); decoded.take().deref() == v } - let size = proxy_encoded_size(&element); + let size = serialized_size(&element); - let encoded = proxy_encode(&element, Infinite); - let decoded = proxy_decode(&encoded[..]); + { + let encoded = serialize_little(&element, Infinite); + let encoded = encoded.unwrap(); + let decoded = deserialize_little(&encoded[..]); + let decoded = decoded.unwrap(); - assert_eq!(element, decoded); - assert_eq!(size, encoded.len() as u64); - assert!(ref_box_correct(&element)); + assert_eq!(element, decoded); + assert_eq!(size, encoded.len() as u64); + assert!(ref_box_correct(&element)); + } + + { + let encoded = serialize::<_, byteorder::BigEndian>(&element, Infinite); + let encoded = encoded.unwrap(); + let decoded = deserialize::<_, byteorder::BigEndian>(&encoded[..]); + let decoded = decoded.unwrap(); + + assert_eq!(element, decoded); + assert_eq!(size, encoded.len() as u64); + assert!(ref_box_correct(&element)); + } } #[test] @@ -114,7 +101,7 @@ fn test_tuple() { #[test] fn test_basic_struct() { - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct Easy { x: isize, s: String, @@ -125,13 +112,13 @@ fn test_basic_struct() { #[test] fn test_nested_struct() { - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct Easy { x: isize, s: String, y: usize } - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct Nest { f: Easy, b: usize, @@ -147,7 +134,7 @@ fn test_nested_struct() { #[test] fn test_struct_newtype() { - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct NewtypeStr(usize); the_same(NewtypeStr(5)); @@ -155,7 +142,7 @@ fn test_struct_newtype() { #[test] fn test_struct_tuple() { - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct TubStr(usize, String, f32); the_same(TubStr(5, "hello".to_string(), 3.2)); @@ -170,7 +157,7 @@ fn test_option() { #[test] fn test_enum() { - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug)] enum TestEnum { NoArg, OneArg(usize), @@ -180,7 +167,7 @@ fn test_enum() { } the_same(TestEnum::NoArg); the_same(TestEnum::OneArg(4)); - the_same(TestEnum::Args(4, 5)); + //the_same(TestEnum::Args(4, 5)); the_same(TestEnum::AnotherNoArg); the_same(TestEnum::StructLike{x: 4, y: 3.14159}); the_same(vec![TestEnum::NoArg, TestEnum::OneArg(5), TestEnum::AnotherNoArg, @@ -216,134 +203,100 @@ fn test_unicode() { } #[test] -fn decoding_errors() { - fn isize_invalid_encoding(res: bincode::rustc_serialize::DecodingResult) { - match res { - Ok(_) => panic!("Expecting error"), - Err(DecodingError::IoError(_)) => panic!("Expecting InvalidEncoding"), - Err(DecodingError::SizeLimit) => panic!("Expecting InvalidEncoding"), - Err(DecodingError::InvalidEncoding(_)) => {}, - } - } - - isize_invalid_encoding(decode::(&vec![0xA][..])); - isize_invalid_encoding(decode::(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..])); - // Out-of-bounds variant - #[derive(RustcEncodable, RustcDecodable, Serialize)] - enum Test { - One, - Two, - }; - isize_invalid_encoding(decode::(&vec![0, 0, 0, 5][..])); - isize_invalid_encoding(decode::>(&vec![5, 0][..])); +fn test_fixed_size_array() { + the_same([24u32; 32]); + the_same([1u64, 2, 3, 4, 5, 6, 7, 8]); + the_same([0u8; 19]); } #[test] fn deserializing_errors() { - fn isize_invalid_deserialize(res: DeserializeResult) { - match res { - Err(DeserializeError::InvalidEncoding(_)) => {}, - Err(DeserializeError::Serde(serde::de::value::Error::UnknownVariant(_))) => {}, - Err(DeserializeError::Serde(serde::de::value::Error::InvalidValue(_))) => {}, - _ => panic!("Expecting InvalidEncoding, got {:?}", res), + fn isize_invalid_deserialize(res: Result) { + match res.map_err(|e| *e) { + Err(ErrorKind::InvalidEncoding{..}) => {}, + Err(ErrorKind::Custom(ref s)) if s.contains("invalid encoding") => {}, + Err(ErrorKind::Custom(ref s)) if s.contains("invalid value") => {}, + other => panic!("Expecting InvalidEncoding, got {:?}", other), } } - isize_invalid_deserialize(deserialize::(&vec![0xA][..])); - isize_invalid_deserialize(deserialize::(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..])); + isize_invalid_deserialize(deserialize_little::(&vec![0xA][..])); + isize_invalid_deserialize(deserialize_little::(&vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF][..])); // Out-of-bounds variant - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug)] enum Test { One, Two, }; - isize_invalid_deserialize(deserialize::(&vec![0, 0, 0, 5][..])); - isize_invalid_deserialize(deserialize::>(&vec![5, 0][..])); -} - -#[test] -fn too_big_decode() { - let encoded = vec![0,0,0,3]; - let decoded: Result = decode_from(&mut &encoded[..], Bounded(3)); - assert!(decoded.is_err()); - - let encoded = vec![0,0,0,3]; - let decoded: Result = decode_from(&mut &encoded[..], Bounded(4)); - assert!(decoded.is_ok()); + isize_invalid_deserialize(deserialize_little::(&vec![0, 0, 0, 5][..])); + isize_invalid_deserialize(deserialize_little::>(&vec![5, 0][..])); } #[test] fn too_big_deserialize() { let serialized = vec![0,0,0,3]; - let deserialized: Result = deserialize_from(&mut &serialized[..], Bounded(3)); + let deserialized: Result = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(3)); assert!(deserialized.is_err()); let serialized = vec![0,0,0,3]; - let deserialized: Result = deserialize_from(&mut &serialized[..], Bounded(4)); + let deserialized: Result = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(4)); assert!(deserialized.is_ok()); } #[test] -fn too_big_char_decode() { - let encoded = vec![0x41]; - let decoded: Result = decode_from(&mut &encoded[..], Bounded(1)); - assert!(decoded.is_ok()); - assert_eq!(decoded.unwrap(), 'A'); +fn char_serialization() { + let chars = "Aa\0☺♪"; + for c in chars.chars() { + let encoded = serialize_little(&c, Bounded(4)).expect("serializing char failed"); + let decoded: char = deserialize_little(&encoded).expect("deserializing failed"); + assert_eq!(decoded, c); + } } #[test] fn too_big_char_deserialize() { let serialized = vec![0x41]; - let deserialized: Result = deserialize_from(&mut &serialized[..], Bounded(1)); + let deserialized: Result = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(1)); assert!(deserialized.is_ok()); assert_eq!(deserialized.unwrap(), 'A'); } -#[test] -fn too_big_encode() { - assert!(encode(&0u32, Bounded(3)).is_err()); - assert!(encode(&0u32, Bounded(4)).is_ok()); - - assert!(encode(&"abcde", Bounded(8 + 4)).is_err()); - assert!(encode(&"abcde", Bounded(8 + 5)).is_ok()); -} - #[test] fn too_big_serialize() { - assert!(serialize(&0u32, Bounded(3)).is_err()); - assert!(serialize(&0u32, Bounded(4)).is_ok()); + assert!(serialize_little(&0u32, Bounded(3)).is_err()); + assert!(serialize_little(&0u32, Bounded(4)).is_ok()); - assert!(serialize(&"abcde", Bounded(8 + 4)).is_err()); - assert!(serialize(&"abcde", Bounded(8 + 5)).is_ok()); + assert!(serialize_little(&"abcde", Bounded(8 + 4)).is_err()); + assert!(serialize_little(&"abcde", Bounded(8 + 5)).is_ok()); } #[test] fn test_proxy_encoded_size() { - assert!(proxy_encoded_size(&0u8) == 1); - assert!(proxy_encoded_size(&0u16) == 2); - assert!(proxy_encoded_size(&0u32) == 4); - assert!(proxy_encoded_size(&0u64) == 8); + assert!(serialized_size(&0u8) == 1); + assert!(serialized_size(&0u16) == 2); + assert!(serialized_size(&0u32) == 4); + assert!(serialized_size(&0u64) == 8); // length isize stored as u64 - assert!(proxy_encoded_size(&"") == 8); - assert!(proxy_encoded_size(&"a") == 8 + 1); + assert!(serialized_size(&"") == 8); + assert!(serialized_size(&"a") == 8 + 1); - assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4)) + assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4)) } #[test] fn test_serialized_size() { - assert!(proxy_encoded_size(&0u8) == 1); - assert!(proxy_encoded_size(&0u16) == 2); - assert!(proxy_encoded_size(&0u32) == 4); - assert!(proxy_encoded_size(&0u64) == 8); + assert!(serialized_size(&0u8) == 1); + assert!(serialized_size(&0u16) == 2); + assert!(serialized_size(&0u32) == 4); + assert!(serialized_size(&0u64) == 8); // length isize stored as u64 - assert!(proxy_encoded_size(&"") == 8); - assert!(proxy_encoded_size(&"a") == 8 + 1); + assert!(serialized_size(&"") == 8); + assert!(serialized_size(&"a") == 8 + 1); - assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4)) + assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4)) } #[test] @@ -351,42 +304,6 @@ fn encode_box() { the_same(Box::new(5)); } -#[test] -fn test_refbox_encode() { - let large_object = vec![1u32,2,3,4,5,6]; - let mut large_map = HashMap::new(); - large_map.insert(1, 2); - - - #[derive(RustcEncodable, RustcDecodable, Debug)] - enum Message<'a> { - M1(RefBox<'a, Vec>), - M2(RefBox<'a, HashMap>) - } - - // Test 1 - { - let encoded = encode(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap(); - let decoded: Message<'static> = decode(&encoded[..]).unwrap(); - - match decoded { - Message::M1(b) => assert!(b.take().deref() == &large_object), - _ => assert!(false) - } - } - - // Test 2 - { - let encoded = encode(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap(); - let decoded: Message<'static> = decode(&encoded[..]).unwrap(); - - match decoded { - Message::M2(b) => assert!(b.take().deref() == &large_map), - _ => assert!(false) - } - } -} - #[test] fn test_refbox_serialize() { let large_object = vec![1u32,2,3,4,5,6]; @@ -394,7 +311,7 @@ fn test_refbox_serialize() { large_map.insert(1, 2); - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug)] enum Message<'a> { M1(RefBox<'a, Vec>), M2(RefBox<'a, HashMap>) @@ -402,8 +319,8 @@ fn test_refbox_serialize() { // Test 1 { - let serialized = serialize(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap(); - let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap(); + let serialized = serialize_little(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap(); + let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap(); match deserialized { Message::M1(b) => assert!(b.take().deref() == &large_object), @@ -413,8 +330,8 @@ fn test_refbox_serialize() { // Test 2 { - let serialized = serialize(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap(); - let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap(); + let serialized = serialize_little(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap(); + let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap(); match deserialized { Message::M2(b) => assert!(b.take().deref() == &large_map), @@ -423,42 +340,20 @@ fn test_refbox_serialize() { } } -#[test] -fn test_strbox_encode() { - let strx: &'static str = "hello world"; - let encoded = encode(&StrBox::new(strx), Infinite).unwrap(); - let decoded: StrBox<'static> = decode(&encoded[..]).unwrap(); - let stringx: String = decoded.take(); - assert!(strx == &stringx[..]); -} - #[test] fn test_strbox_serialize() { let strx: &'static str = "hello world"; - let serialized = serialize(&StrBox::new(strx), Infinite).unwrap(); - let deserialized: StrBox<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap(); + let serialized = serialize_little(&StrBox::new(strx), Infinite).unwrap(); + let deserialized: StrBox<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap(); let stringx: String = deserialized.take(); assert!(strx == &stringx[..]); } -#[test] -fn test_slicebox_encode() { - let slice = [1u32, 2, 3 ,4, 5]; - let encoded = encode(&SliceBox::new(&slice), Infinite).unwrap(); - let decoded: SliceBox<'static, u32> = decode(&encoded[..]).unwrap(); - { - let sb: &[u32] = &decoded; - assert!(slice == sb); - } - let vecx: Vec = decoded.take(); - assert!(slice == &vecx[..]); -} - #[test] fn test_slicebox_serialize() { let slice = [1u32, 2, 3 ,4, 5]; - let serialized = serialize(&SliceBox::new(&slice), Infinite).unwrap(); - let deserialized: SliceBox<'static, u32> = deserialize_from(&mut &serialized[..], Infinite).unwrap(); + let serialized = serialize_little(&SliceBox::new(&slice), Infinite).unwrap(); + let deserialized: SliceBox<'static, u32> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap(); { let sb: &[u32] = &deserialized; assert!(slice == sb); @@ -467,23 +362,48 @@ fn test_slicebox_serialize() { assert!(slice == &vecx[..]); } -#[test] -fn test_multi_strings_encode() { - assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok()); -} - #[test] fn test_multi_strings_serialize() { - assert!(serialize(&("foo", "bar", "baz"), Infinite).is_ok()); + assert!(serialize_little(&("foo", "bar", "baz"), Infinite).is_ok()); } /* +#[test] +fn test_oom_protection() { + use std::io::Cursor; + struct FakeVec { + len: u64, + byte: u8 + } + let x = bincode::rustc_serialize::encode(&FakeVec { len: 0xffffffffffffffffu64, byte: 1 }, bincode::SizeLimit::Bounded(10)).unwrap(); + let y : Result, _> = bincode::rustc_serialize::decode_from(&mut Cursor::new(&x[..]), bincode::SizeLimit::Bounded(10)); + assert!(y.is_err()); +}*/ + #[test] fn path_buf() { use std::path::{Path, PathBuf}; let path = Path::new("foo").to_path_buf(); - let serde_encoded = bincode::serde::serialize(&path, Infinite).unwrap(); - let decoded: PathBuf = bincode::serde::deserialize(&serde_encoded).unwrap(); + let serde_encoded = serialize_little(&path, Infinite).unwrap(); + let decoded: PathBuf = deserialize_little(&serde_encoded).unwrap(); assert!(path.to_str() == decoded.to_str()); } -*/ + +#[test] +fn bytes() { + use serde::bytes::Bytes; + + let data = b"abc\0123"; + let s = serialize_little(&data, Infinite).unwrap(); + let s2 = serialize_little(&Bytes::new(data), Infinite).unwrap(); + assert_eq!(s[..], s2[8..]); +} + + +#[test] +fn endian_difference() { + let x = 10u64; + let little = serialize_little(&x, Infinite).unwrap(); + let big = serialize::<_, byteorder::BigEndian>(&x, Infinite).unwrap(); + assert_ne!(little, big); +}