From 772b1da6df4ed698da594add878cd43a3e03a920 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Sun, 3 Apr 2016 04:51:30 -0700 Subject: [PATCH 01/42] Revert "Respect size limits in read_seq and read_map." This reverts commit 1e21e5d13b21472e2d23ef08feb0ed4372295ef8. --- src/rustc_serialize/reader.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs index 1be8304..a6a70bd 100644 --- a/src/rustc_serialize/reader.rs +++ b/src/rustc_serialize/reader.rs @@ -345,18 +345,6 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult { let len = try!(self.read_usize()); - match self.size_limit { - SizeLimit::Infinite => (), - SizeLimit::Bounded(x) => { - let overflow = match self.read.checked_add(len as u64) { - Some(y) => y > x, - None => true, - }; - if overflow { - return Err(DecodingError::SizeLimit); - } - }, - }; f(self, len) } fn read_seq_elt(&mut self, _: usize, f: F) -> DecodingResult @@ -368,18 +356,6 @@ impl<'a, R: Read> Decoder for DecoderReader<'a, R> { where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult { let len = try!(self.read_usize()); - match self.size_limit { - SizeLimit::Infinite => (), - SizeLimit::Bounded(x) => { - let overflow = match self.read.checked_add(len as u64) { - Some(y) => y > x, - None => true, - }; - if overflow { - return Err(DecodingError::SizeLimit); - } - }, - }; f(self, len) } fn read_map_elt_key(&mut self, _: usize, f: F) -> DecodingResult From c819545c5083843619361410ddc735c2e9e93a4d Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Mon, 4 Apr 2016 08:08:59 -0700 Subject: [PATCH 02/42] add more tests --- tests/test.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index e2540ea..66d3a0b 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -477,7 +477,19 @@ fn test_multi_strings_serialize() { assert!(serialize(&("foo", "bar", "baz"), Infinite).is_ok()); } -/* +#[test] +fn test_oom_protection() { + use std::io::Cursor; + #[derive(RustcEncodable, RustcDecodable)] + 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}; @@ -486,4 +498,3 @@ fn path_buf() { let decoded: PathBuf = bincode::serde::deserialize(&serde_encoded).unwrap(); assert!(path.to_str() == decoded.to_str()); } -*/ From 35aa19b6fb804d306fa9a8efb2c1b6ab322443f0 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Mon, 4 Apr 2016 13:34:18 -0700 Subject: [PATCH 03/42] bump cargo version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 83d96f2..66fea16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.1" +version = "0.5.2" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From 127380a5068f9bf5d09a854984796d51e9af3b4d Mon Sep 17 00:00:00 2001 From: Brian Bowman Date: Thu, 7 Apr 2016 03:05:41 -0500 Subject: [PATCH 04/42] fix typo --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 1baf135..4a0f78e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,7 +66,7 @@ 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, From 183c28e363aabe04f58b243faf237768f13dc206 Mon Sep 17 00:00:00 2001 From: Jayson Reis Date: Tue, 12 Apr 2016 18:26:18 +0200 Subject: [PATCH 05/42] Upgrade byteorder to 0.5.x (#68) --- Cargo.toml | 2 +- src/rustc_serialize/reader.rs | 12 ++---------- src/rustc_serialize/writer.rs | 11 ++--------- src/serde/reader.rs | 11 ----------- src/serde/writer.rs | 11 ++--------- 5 files changed, 7 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 66fea16..aba39e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ description = "A binary serialization / deserialization strategy and implementat [dependencies] rustc-serialize = "0.3.*" -byteorder = "0.4.*" +byteorder = "0.5.*" num = "0.1.*" serde = "0.7.*" diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs index a6a70bd..b8af40f 100644 --- a/src/rustc_serialize/reader.rs +++ b/src/rustc_serialize/reader.rs @@ -7,7 +7,6 @@ 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)] @@ -61,15 +60,8 @@ impl fmt::Display for DecodingError { 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 - }) - } +fn wrap_io(err: IoError) -> DecodingError { + DecodingError::IoError(err) } impl Error for DecodingError { diff --git a/src/rustc_serialize/writer.rs b/src/rustc_serialize/writer.rs index cb50a88..04dd1e3 100644 --- a/src/rustc_serialize/writer.rs +++ b/src/rustc_serialize/writer.rs @@ -1,13 +1,11 @@ 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; @@ -37,13 +35,8 @@ pub struct SizeChecker { 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")) - } +fn wrap_io(err: IoError) -> EncodingError { + EncodingError::IoError(err) } impl fmt::Display for EncodingError { diff --git a/src/serde/reader.rs b/src/serde/reader.rs index f0a957c..3b60e6b 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -4,7 +4,6 @@ use std::error::Error; use std::fmt; use std::convert::From; -use byteorder::Error as ByteOrderError; use byteorder::{BigEndian, ReadBytesExt}; use num; use serde_crate as serde; @@ -77,16 +76,6 @@ impl From for DeserializeError { } } -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) diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 3f8e71b..6469062 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -1,14 +1,12 @@ 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 serde_crate as serde; use byteorder::{BigEndian, WriteBytesExt}; -use byteorder::Error as ByteOrderError; pub type SerializeResult = Result; @@ -35,13 +33,8 @@ pub struct Serializer<'a, W: 'a> { writer: &'a mut W, } -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")) - } +fn wrap_io(err: IoError) -> SerializeError { + SerializeError::IoError(err) } impl serde::ser::Error for SerializeError { From 21329a0e53ac4f35ae61223a169e5885fe3160da Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 12 Apr 2016 09:28:21 -0700 Subject: [PATCH 06/42] v0.5.3 --- Cargo.toml | 2 +- src/rustc_serialize/mod.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aba39e1..87ad675 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.2" +version = "0.5.3" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" diff --git a/src/rustc_serialize/mod.rs b/src/rustc_serialize/mod.rs index b7565ed..694eb24 100644 --- a/src/rustc_serialize/mod.rs +++ b/src/rustc_serialize/mod.rs @@ -100,4 +100,3 @@ 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) } - From c2fc3af47cceba4c6e5b2cfd2b8f0ff18939c99d Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 12 Apr 2016 10:28:55 -0700 Subject: [PATCH 07/42] Better travis tests (#69) Use multirust to switch between language versions. Only run tests on nightly (because the serde macros won't build anywhere else). --- .travis.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 42fe126..b67e3bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,4 @@ -language: rust -rust: - - stable - - beta - - nightly - +lang: c after_success: | [ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] && @@ -12,10 +7,21 @@ after_success: | 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: + matrix: + - CHANNEL='stable' + - CHANNEL='beta' + - CHANNEL='nightly' global: - secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI= -matrix: - allow_failures: - - rust: stable - - rust: beta + +install: + - curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh > ./rustup.sh + - chmod +x ./rustup.sh + - ./rustup.sh --yes + +script: + - multirust default $CHANNEL + - cargo build + - if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi From ff69e6f3e103ccc2f066b5de374455076a83e85e Mon Sep 17 00:00:00 2001 From: Alexander Bulaev Date: Fri, 15 Apr 2016 22:03:32 +0400 Subject: [PATCH 08/42] Add cargo features for rustc-serialize and serde (#70) * Add cargo features for rustc-serialize and serde If you only really need one of them * Check that both "serde" and "rustc-serialize" are compiling * Minor: change Travis build order --- .travis.yml | 2 ++ Cargo.toml | 7 +++++-- src/lib.rs | 4 ++++ src/refbox.rs | 20 ++++++++++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b67e3bf..23b588e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,4 +24,6 @@ install: script: - multirust default $CHANNEL - cargo build + - cargo build --no-default-features --features "rustc-serialize" + - cargo build --no-default-features --features "serde" - if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi diff --git a/Cargo.toml b/Cargo.toml index 87ad675..8851bda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,13 @@ license = "MIT" description = "A binary serialization / deserialization strategy and implementation." [dependencies] -rustc-serialize = "0.3.*" +rustc-serialize = { version = "0.3.*", optional = true } byteorder = "0.5.*" num = "0.1.*" -serde = "0.7.*" +serde = { version = "0.7.*", optional = true } [dev-dependencies] serde_macros = "0.7.*" + +[features] +default = ["rustc-serialize", "serde"] diff --git a/src/lib.rs b/src/lib.rs index 4a0f78e..3285231 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,16 +37,20 @@ #![doc(html_logo_url = "./icon.png")] +#[cfg(feature = "rustc-serialize")] extern crate rustc_serialize as rustc_serialize_crate; extern crate byteorder; extern crate num; +#[cfg(feature = "serde")] extern crate serde as serde_crate; pub use refbox::{RefBox, StrBox, SliceBox}; mod refbox; +#[cfg(feature = "rustc-serialize")] pub mod rustc_serialize; +#[cfg(feature = "serde")] pub mod serde; /// A limit on the amount of bytes that can be read or written. diff --git a/src/refbox.rs b/src/refbox.rs index b115357..c158b8d 100644 --- a/src/refbox.rs +++ b/src/refbox.rs @@ -1,8 +1,10 @@ use std::boxed::Box; use std::ops::Deref; +#[cfg(feature = "rustc-serialize")] use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder}; +#[cfg(feature = "serde")] use serde_crate as serde; /// A struct for encoding nested reference types. @@ -139,13 +141,14 @@ impl RefBox<'static, T> { } } - +#[cfg(feature = "rustc-serialize")] impl <'a, T: Encodable> Encodable for RefBox<'a, T> { fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.inner.encode(s) } } +#[cfg(feature = "rustc-serialize")] impl Decodable for RefBox<'static, T> { fn decode(d: &mut D) -> Result, D::Error> { let inner = try!(Decodable::decode(d)); @@ -153,6 +156,7 @@ impl Decodable for RefBox<'static, T> { } } +#[cfg(feature = "serde")] impl<'a, T> serde::Serialize for RefBox<'a, T> where T: serde::Serialize, { @@ -163,6 +167,7 @@ impl<'a, T> serde::Serialize for RefBox<'a, T> } } +#[cfg(feature = "serde")] impl serde::Deserialize for RefBox<'static, T> { fn deserialize(deserializer: &mut D) -> Result where D: serde::Deserializer @@ -234,12 +239,14 @@ impl StrBox<'static> { } } +#[cfg(feature = "rustc-serialize")] impl <'a> Encodable for StrBox<'a> { fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.inner.encode(s) } } +#[cfg(feature = "rustc-serialize")] impl Decodable for StrBox<'static> { fn decode(d: &mut D) -> Result, D::Error> { let inner: RefBoxInner<'static, str, String> = try!(Decodable::decode(d)); @@ -247,6 +254,7 @@ impl Decodable for StrBox<'static> { } } +#[cfg(feature = "serde")] impl<'a> serde::Serialize for StrBox<'a> { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: serde::Serializer @@ -255,6 +263,7 @@ impl<'a> serde::Serialize for StrBox<'a> { } } +#[cfg(feature = "serde")] impl serde::Deserialize for StrBox<'static> { fn deserialize(deserializer: &mut D) -> Result where D: serde::Deserializer @@ -321,12 +330,14 @@ impl SliceBox<'static, T> { } } +#[cfg(feature = "rustc-serialize")] impl <'a, T: Encodable> Encodable for SliceBox<'a, T> { fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.inner.encode(s) } } +#[cfg(feature = "rustc-serialize")] impl Decodable for SliceBox<'static, T> { fn decode(d: &mut D) -> Result, D::Error> { let inner: RefBoxInner<'static, [T], Vec> = try!(Decodable::decode(d)); @@ -334,6 +345,7 @@ impl Decodable for SliceBox<'static, T> { } } +#[cfg(feature = "serde")] impl<'a, T> serde::Serialize for SliceBox<'a, T> where T: serde::Serialize, { @@ -344,6 +356,7 @@ impl<'a, T> serde::Serialize for SliceBox<'a, T> } } +#[cfg(feature = "serde")] impl serde::Deserialize for SliceBox<'static, T> { fn deserialize(deserializer: &mut D) -> Result where D: serde::Deserializer @@ -353,6 +366,7 @@ impl serde::Deserialize for SliceBox<'static, T> { } } +#[cfg(feature = "rustc-serialize")] impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> { fn encode(&self, s: &mut S) -> Result<(), S::Error> { match self { @@ -362,6 +376,7 @@ impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, } } +#[cfg(feature = "serde")] impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> where A: serde::Serialize, B: serde::Serialize, @@ -376,7 +391,7 @@ impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> } } - +#[cfg(feature = "rustc-serialize")] impl Decodable for RefBoxInner<'static, A, B> { fn decode(d: &mut D) -> Result, D::Error> { let decoded = try!(Decodable::decode(d)); @@ -384,6 +399,7 @@ impl Decodable for RefBoxInner<'static, A, B> { } } +#[cfg(feature = "serde")] impl serde::Deserialize for RefBoxInner<'static, A, B> where B: serde::Deserialize, { From 834e4c365636b72c35f0dd8a0d6947a61e758f9a Mon Sep 17 00:00:00 2001 From: Alexander Bulaev Date: Sat, 16 Apr 2016 01:22:39 +0400 Subject: [PATCH 09/42] Don't pull `rustc-serialize` from `num` (#71) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8851bda..fbad54a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ description = "A binary serialization / deserialization strategy and implementat [dependencies] rustc-serialize = { version = "0.3.*", optional = true } byteorder = "0.5.*" -num = "0.1.*" +num = { version = "0.1.*", default-features = false } serde = { version = "0.7.*", optional = true } [dev-dependencies] From c7bdb4a90c1c02174272350f32ce69d714c83b8d Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 21 Apr 2016 18:28:33 +0200 Subject: [PATCH 10/42] Use num-traits. (#72) --- Cargo.toml | 2 +- src/lib.rs | 2 +- src/serde/reader.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fbad54a..3b0434b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ description = "A binary serialization / deserialization strategy and implementat [dependencies] rustc-serialize = { version = "0.3.*", optional = true } byteorder = "0.5.*" -num = { version = "0.1.*", default-features = false } +num-traits = "0.1.32" serde = { version = "0.7.*", optional = true } [dev-dependencies] diff --git a/src/lib.rs b/src/lib.rs index 3285231..138a9e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ #[cfg(feature = "rustc-serialize")] extern crate rustc_serialize as rustc_serialize_crate; extern crate byteorder; -extern crate num; +extern crate num_traits; #[cfg(feature = "serde")] extern crate serde as serde_crate; diff --git a/src/serde/reader.rs b/src/serde/reader.rs index 3b60e6b..353b13d 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -5,7 +5,7 @@ use std::fmt; use std::convert::From; use byteorder::{BigEndian, ReadBytesExt}; -use num; +use num_traits; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; use serde_crate::de::Deserializer as SerdeDeserializer; @@ -222,7 +222,7 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { { try!(self.read_type::()); let value = try!(self.reader.read_u64::()); - match num::cast(value) { + match num_traits::cast(value) { Some(value) => visitor.visit_usize(value), None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected usize".into()))) } @@ -242,7 +242,7 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { { try!(self.read_type::()); let value = try!(self.reader.read_i64::()); - match num::cast(value) { + match num_traits::cast(value) { Some(value) => visitor.visit_isize(value), None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected isize".into()))), } From 45cfc7da9a37402b06210b98a5dce53a2465cb7c Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Thu, 28 Apr 2016 17:31:36 -0700 Subject: [PATCH 11/42] bump version number --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3b0434b..648ed3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.3" +version = "0.5.6" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From 629d7bc640ab69c9d8de5fe93bc9a7564991f5ba Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 19 Jun 2016 13:23:21 -0700 Subject: [PATCH 12/42] Impl Deserialize for non-'static lifetimes (#79) --- src/refbox.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/refbox.rs b/src/refbox.rs index c158b8d..fb91124 100644 --- a/src/refbox.rs +++ b/src/refbox.rs @@ -168,7 +168,7 @@ impl<'a, T> serde::Serialize for RefBox<'a, T> } #[cfg(feature = "serde")] -impl serde::Deserialize for RefBox<'static, T> { +impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> { fn deserialize(deserializer: &mut D) -> Result where D: serde::Deserializer { @@ -357,7 +357,7 @@ impl<'a, T> serde::Serialize for SliceBox<'a, T> } #[cfg(feature = "serde")] -impl serde::Deserialize for SliceBox<'static, T> { +impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> { fn deserialize(deserializer: &mut D) -> Result where D: serde::Deserializer { @@ -400,7 +400,7 @@ impl Decodable for RefBoxInner<'static, A, B> { } #[cfg(feature = "serde")] -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 From e5a524ed2834cb8ca8ead43579c13043b512b58e Mon Sep 17 00:00:00 2001 From: Dmitry <0nkery@users.noreply.github.com> Date: Mon, 20 Jun 2016 03:29:10 +0700 Subject: [PATCH 13/42] Fixed size array deserialization (#76) * Attempt to implement hint for fixed size arrays. * Removed wrong visitor + tests. * Removed extra new line. --- src/serde/reader.rs | 8 ++++++++ tests/test.rs | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/serde/reader.rs b/src/serde/reader.rs index 353b13d..854262a 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -345,6 +345,14 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { visitor.visit_seq(TupleVisitor(self)) } + fn deserialize_fixed_size_array(&mut self, + _: usize, + visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + self.deserialize_seq(visitor) + } + fn deserialize_option(&mut self, mut visitor: V) -> DeserializeResult where V: serde::de::Visitor, { diff --git a/tests/test.rs b/tests/test.rs index 66d3a0b..f5f067c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -215,6 +215,13 @@ fn test_unicode() { the_same("aåååååååa".to_string()); } +#[test] +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 decoding_errors() { fn isize_invalid_encoding(res: bincode::rustc_serialize::DecodingResult) { From 2ae255e63435c50cad22f5ffe15307c1cd7b0cbc Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Sun, 19 Jun 2016 13:30:27 -0700 Subject: [PATCH 14/42] 0.5.7 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 648ed3b..a7dd7ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.6" +version = "0.5.7" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From 2eee182f1fa83997b6a8f6019e43893fa22aa4cf Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 30 Jun 2016 14:02:07 +0200 Subject: [PATCH 15/42] fix char serialization and deserialization --- src/serde/reader.rs | 3 +-- src/serde/writer.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++ tests/test.rs | 10 +++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/serde/reader.rs b/src/serde/reader.rs index 854262a..3d58e34 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -289,7 +289,6 @@ 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) } @@ -345,7 +344,7 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { visitor.visit_seq(TupleVisitor(self)) } - fn deserialize_fixed_size_array(&mut self, + fn deserialize_fixed_size_array(&mut self, _: usize, visitor: V) -> DeserializeResult where V: serde::de::Visitor, diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 6469062..6e1afb9 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -141,6 +141,10 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { self.writer.write_all(v.as_bytes()).map_err(SerializeError::IoError) } + fn serialize_char(&mut self, c: char) -> SerializeResult<()> { + self.writer.write_all(encode_utf8(c).as_slice()).map_err(SerializeError::IoError) + } + fn serialize_none(&mut self) -> SerializeResult<()> { self.writer.write_u8(0).map_err(wrap_io) } @@ -352,6 +356,10 @@ impl serde::Serializer for SizeChecker { self.add_raw(v.len()) } + fn serialize_char(&mut self, c: char) -> SerializeResult<()> { + self.add_raw(encode_utf8(c).as_slice().len()) + } + fn serialize_none(&mut self) -> SerializeResult<()> { self.add_value(0 as u8) } @@ -464,3 +472,47 @@ impl serde::Serializer for SizeChecker { 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 f5f067c..9039e9e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -290,6 +290,16 @@ fn too_big_deserialize() { assert!(deserialized.is_ok()); } +#[test] +fn char_serialization() { + let chars = "Aa\0☺♪"; + for c in chars.chars() { + let encoded = serialize(&c, Bounded(4)).expect("serializing char failed"); + let decoded: char = deserialize(&encoded).expect("deserializing failed"); + assert_eq!(decoded, c); + } +} + #[test] fn too_big_char_decode() { let encoded = vec![0x41]; From 8f98e8789d1bdc11b886c63b0ae967492200e946 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 30 Jun 2016 14:13:10 +0200 Subject: [PATCH 16/42] 0.5.8 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a7dd7ff..97f800a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.7" +version = "0.5.8" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From c5073e83e56ae16e52abdc8356aceaec3e9654a0 Mon Sep 17 00:00:00 2001 From: Cobrand Date: Fri, 8 Jul 2016 15:53:43 +0200 Subject: [PATCH 17/42] pub used InvalidEncoding in serde+rustc_serialize so it shows in `cargo doc` (#82) * Removed unused import warning * pub use InvalidEncoding in serde+rustc_serialize * Made both fields of InvalidEncoding public so it can be used without Display or Debug traits (e.g. pattern matching) * Export of InvalidEncoding in rustc_serialize/serde make them visible in `cargo doc` --- src/rustc_serialize/mod.rs | 2 +- src/rustc_serialize/reader.rs | 4 ++-- src/serde/mod.rs | 2 +- src/serde/reader.rs | 5 ++--- tests/test.rs | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/rustc_serialize/mod.rs b/src/rustc_serialize/mod.rs index 694eb24..2b75e80 100644 --- a/src/rustc_serialize/mod.rs +++ b/src/rustc_serialize/mod.rs @@ -7,7 +7,7 @@ use std::io::{Write, Read}; use ::SizeLimit; pub use self::writer::{SizeChecker, EncoderWriter, EncodingResult, EncodingError}; -pub use self::reader::{DecoderReader, DecodingResult, DecodingError}; +pub use self::reader::{DecoderReader, DecodingResult, DecodingError, InvalidEncoding}; mod reader; mod writer; diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs index b8af40f..ba1fd31 100644 --- a/src/rustc_serialize/reader.rs +++ b/src/rustc_serialize/reader.rs @@ -11,8 +11,8 @@ use ::SizeLimit; #[derive(Eq, PartialEq, Clone, Debug)] pub struct InvalidEncoding { - desc: &'static str, - detail: Option, + pub desc: &'static str, + pub detail: Option, } impl fmt::Display for InvalidEncoding { diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 76f648a..e570111 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -9,6 +9,7 @@ pub use self::reader::{ Deserializer, DeserializeResult, DeserializeError, + InvalidEncoding }; pub use self::writer::{ @@ -120,4 +121,3 @@ pub fn deserialize(bytes: &[u8]) -> DeserializeResult let mut reader = bytes; deserialize_from(&mut reader, SizeLimit::Infinite) } - diff --git a/src/serde/reader.rs b/src/serde/reader.rs index 3d58e34..b5d1691 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -8,14 +8,13 @@ use byteorder::{BigEndian, ReadBytesExt}; use num_traits; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; -use serde_crate::de::Deserializer as SerdeDeserializer; use ::SizeLimit; #[derive(Eq, PartialEq, Clone, Debug)] pub struct InvalidEncoding { - desc: &'static str, - detail: Option, + pub desc: &'static str, + pub detail: Option, } impl fmt::Display for InvalidEncoding { diff --git a/tests/test.rs b/tests/test.rs index 9039e9e..d114f64 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -9,7 +9,7 @@ use std::fmt::Debug; use std::collections::HashMap; use std::ops::Deref; -use rustc_serialize::{Encoder, Decoder, Encodable, Decodable}; +use rustc_serialize::{Encodable, Decodable}; use bincode::{RefBox, StrBox, SliceBox}; From 23cb6ea79c5fd23961e8f359a5878488328dbc02 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Fri, 8 Jul 2016 06:55:29 -0700 Subject: [PATCH 18/42] 0.5.9 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 97f800a..13b2870 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.8" +version = "0.5.9" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From 95b414a1849f579891e64f29911e30a0649cb54c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 28 Jul 2016 12:23:18 -0700 Subject: [PATCH 19/42] Update to serde 0.8.0 (#84) --- Cargo.toml | 4 +- src/serde/reader.rs | 77 ++++++-- src/serde/writer.rs | 418 +++++++++++++++++++++++++++++--------------- 3 files changed, 337 insertions(+), 162 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 97f800a..b69cb55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,10 +14,10 @@ description = "A binary serialization / deserialization strategy and implementat rustc-serialize = { version = "0.3.*", optional = true } byteorder = "0.5.*" num-traits = "0.1.32" -serde = { version = "0.7.*", optional = true } +serde = { version = "0.8.*", optional = true } [dev-dependencies] -serde_macros = "0.7.*" +serde_macros = "0.8.*" [features] default = ["rustc-serialize", "serde"] diff --git a/src/serde/reader.rs b/src/serde/reader.rs index b5d1691..00ea18c 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -138,9 +138,7 @@ 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> { self.read += count; match self.size_limit { @@ -154,6 +152,20 @@ impl <'a, A> Deserializer<'a, A> { use std::mem::size_of; self.read_bytes(size_of::() as u64) } + + fn read_string(&mut self) -> DeserializeResult { + 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)); + + String::from_utf8(buffer).map_err(|err| + DeserializeError::InvalidEncoding(InvalidEncoding { + desc: "error while decoding utf8 string", + detail: Some(format!("Deserialize error: {}", err)) + })) + } } macro_rules! impl_nums { @@ -291,22 +303,22 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { visitor.visit_char(res) } + fn deserialize_str(&mut self, mut visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + visitor.visit_str(&try!(self.read_string())) + } + fn deserialize_string(&mut self, mut visitor: V) -> DeserializeResult where V: serde::de::Visitor, { - let len = try!(serde::Deserialize::deserialize(self)); - try!(self.read_bytes(len)); + visitor.visit_string(try!(self.read_string())) + } - let mut buffer = Vec::new(); - try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer)); - - match String::from_utf8(buffer) { - Ok(s) => visitor.visit_string(s), - Err(err) => Err(DeserializeError::InvalidEncoding(InvalidEncoding { - desc: "error while decoding utf8 string", - detail: Some(format!("Deserialize error: {}", err)) - })), - } + fn deserialize_bytes(&mut self, visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + self.deserialize_seq(visitor) } fn deserialize_enum(&mut self, @@ -343,7 +355,7 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { visitor.visit_seq(TupleVisitor(self)) } - fn deserialize_fixed_size_array(&mut self, + fn deserialize_seq_fixed_size(&mut self, _: usize, visitor: V) -> DeserializeResult where V: serde::de::Visitor, @@ -455,13 +467,46 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { self.deserialize_tuple(fields.len(), visitor) } + fn deserialize_struct_field(&mut self, + _visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + let message = "bincode does not support Deserializer::deserialize_struct_field"; + Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + } + fn deserialize_newtype_struct(&mut self, _name: &str, - mut visitor: V) -> Result + mut visitor: V) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_newtype_struct(self) } + + fn deserialize_unit_struct(&mut self, + _name: &'static str, + mut visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + visitor.visit_unit() + } + + fn deserialize_tuple_struct(&mut self, + _name: &'static str, + len: usize, + visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_ignored_any(&mut self, + _visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + let message = "bincode does not support Deserializer::deserialize_ignored_any"; + Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + } } impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> { diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 6e1afb9..0c3ae3c 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -89,9 +89,18 @@ impl<'a, W: Write> Serializer<'a, W> { impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { type Error = SerializeError; + type SeqState = (); + type TupleState = (); + type TupleStructState = (); + type TupleVariantState = (); + type MapState = (); + type StructState = (); + type StructVariantState = (); fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_bool(&mut self, v: bool) -> SerializeResult<()> { self.writer.write_u8(if v {1} else {0}).map_err(wrap_io) } @@ -112,6 +121,10 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { self.writer.write_u64::(v).map_err(wrap_io) } + fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> { + self.serialize_u64(v as u64) + } + fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { self.writer.write_i8(v).map_err(wrap_io) } @@ -128,6 +141,10 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { self.writer.write_i64::(v).map_err(wrap_io) } + fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> { + self.serialize_i64(v as i64) + } + fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { self.writer.write_f32::(v).map_err(wrap_io) } @@ -145,6 +162,14 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { self.writer.write_all(encode_utf8(c).as_slice()).map_err(SerializeError::IoError) } + fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { + let mut state = try!(self.serialize_seq(Some(v.len()))); + for c in v { + try!(self.serialize_seq_elt(&mut state, c)); + } + self.serialize_seq_end(state) + } + fn serialize_none(&mut self) -> SerializeResult<()> { self.writer.write_u8(0).map_err(wrap_io) } @@ -156,113 +181,150 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { 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(&mut self, len: Option) -> SerializeResult<()> { + let len = len.expect("do not know how to serialize a sequence with no length"); + self.serialize_usize(len) } - 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_elt(&mut self, value: V) -> SerializeResult<()> + fn serialize_seq_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> where V: serde::Serialize, { value.serialize(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)) { } - + fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> { Ok(()) } - fn serialize_map_elt(&mut self, key: K, value: V) -> SerializeResult<()> + fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_struct_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_variant(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> SerializeResult<()> + { + self.add_enum_tag(variant_index) + } + + fn serialize_tuple_variant_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_map(&mut self, len: Option) -> SerializeResult<()> { + let len = len.expect("do not know how to serialize a map with no length"); + self.serialize_usize(len) + } + + fn serialize_map_key(&mut self, _: &mut (), key: K) -> SerializeResult<()> where K: serde::Serialize, - V: serde::Serialize, { - try!(key.serialize(self)); - value.serialize(self) + key.serialize(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_struct_elt(&mut self, _key: &str, value: V) -> SerializeResult<()> + fn serialize_map_value(&mut self, _: &mut (), value: V) -> SerializeResult<()> where V: serde::Serialize, { value.serialize(self) } + fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct_variant(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> SerializeResult<()> + { + self.add_enum_tag(variant_index) + } + + fn serialize_struct_variant_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + fn serialize_newtype_struct(&mut self, - _name: &str, + _name: &'static str, value: T) -> SerializeResult<()> 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(&mut self, + _name: &'static str, variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, + _variant: &'static str, + value: T) -> SerializeResult<()> + 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(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str) -> SerializeResult<()> { + self.add_enum_tag(variant_index) } } @@ -304,9 +366,18 @@ impl SizeChecker { impl serde::Serializer for SizeChecker { type Error = SerializeError; + type SeqState = (); + type TupleState = (); + type TupleStructState = (); + type TupleVariantState = (); + type MapState = (); + type StructState = (); + type StructVariantState = (); fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_bool(&mut self, _: bool) -> SerializeResult<()> { self.add_value(0 as u8) } @@ -327,6 +398,10 @@ impl serde::Serializer for SizeChecker { self.add_value(v) } + fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> { + self.serialize_u64(v as u64) + } + fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { self.add_value(v) } @@ -343,6 +418,10 @@ impl serde::Serializer for SizeChecker { self.add_value(v) } + fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> { + self.serialize_i64(v as i64) + } + fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { self.add_value(v) } @@ -360,6 +439,14 @@ impl serde::Serializer for SizeChecker { self.add_raw(encode_utf8(c).as_slice().len()) } + fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { + let mut state = try!(self.serialize_seq(Some(v.len()))); + for c in v { + try!(self.serialize_seq_elt(&mut state, c)); + } + self.serialize_seq_end(state) + } + fn serialize_none(&mut self) -> SerializeResult<()> { self.add_value(0 as u8) } @@ -371,105 +458,148 @@ impl serde::Serializer for SizeChecker { 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(&mut self, len: Option) -> SerializeResult<()> { + let len = len.expect("do not know how to serialize a sequence with no length"); - try!(self.serialize_usize(len)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + self.serialize_usize(len) } - 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_elt(&mut self, value: V) -> SerializeResult<()> + fn serialize_seq_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> where V: serde::Serialize, { value.serialize(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)) { } - + fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> { Ok(()) } - fn serialize_map_elt(&mut self, key: K, value: V) -> SerializeResult<()> - where K: serde::Serialize, - V: serde::Serialize, - { - try!(key.serialize(self)); - value.serialize(self) + fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> { + self.serialize_seq(Some(len)) } - fn serialize_struct(&mut self, _name: &str, mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, - { - while let Some(()) = try!(visitor.visit(self)) { } - + fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> { Ok(()) } - fn serialize_struct_elt(&mut self, _key: &str, value: V) -> SerializeResult<()> + fn serialize_tuple_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> where V: serde::Serialize, { value.serialize(self) } - fn serialize_unit_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str) -> SerializeResult<()> { + fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_struct_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_tuple_variant(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + _len: usize) -> 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, + fn serialize_tuple_variant_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, { - try!(self.add_enum_tag(variant_index)); - - while let Some(()) = try!(visitor.visit(self)) { } + value.serialize(self) + } + fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> { Ok(()) } - fn serialize_struct_variant(&mut self, - _name: &str, + fn serialize_map(&mut self, len: Option) -> SerializeResult<()> + { + let len = len.expect("do not know how to serialize a map with no length"); + + self.serialize_usize(len) + } + + fn serialize_map_key(&mut self, _: &mut (), key: K) -> SerializeResult<()> + where K: serde::Serialize, + { + key.serialize(self) + } + + fn serialize_map_value(&mut self, _: &mut (), value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_struct_variant(&mut self, + _name: &'static str, variant_index: usize, - _variant: &str, - mut visitor: V) -> SerializeResult<()> - where V: serde::ser::MapVisitor, + _variant: &'static str, + _len: usize) -> SerializeResult<()> + { + self.add_enum_tag(variant_index) + } + + fn serialize_struct_variant_elt(&mut self, _: &mut (), _field: &'static str, value: V) -> SerializeResult<()> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> { + Ok(()) + } + + fn serialize_newtype_struct(&mut self, _name: &'static str, v: V) -> SerializeResult<()> { + v.serialize(self) + } + + fn serialize_unit_variant(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str) -> SerializeResult<()> { + self.add_enum_tag(variant_index) + } + + fn serialize_newtype_variant(&mut self, + _name: &'static str, + variant_index: usize, + _variant: &'static str, + value: V) -> SerializeResult<()> { try!(self.add_enum_tag(variant_index)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) + value.serialize(self) } } From 44ea3bbbdbe65685c7c1e9a911cc3b516c707cfc Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Thu, 28 Jul 2016 12:35:40 -0700 Subject: [PATCH 20/42] 0.6.0 --- Cargo.toml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ac09754..c4befb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.5.9" +version = "0.6.0" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" @@ -8,13 +8,19 @@ documentation = "http://tyoverby.github.io/bincode/bincode/" keywords = ["binary", "encode", "decode", "serialize", "deserialize"] license = "MIT" -description = "A binary serialization / deserialization strategy and implementation." +description = "A binary serialization / deserialization strategy and implementation with serde and rustc-serialize backends." [dependencies] -rustc-serialize = { version = "0.3.*", optional = true } byteorder = "0.5.*" num-traits = "0.1.32" -serde = { version = "0.8.*", optional = true } + +[dependencies.rustc-serialize] +version = "0.3.*" +optional = true + +[dependencies.serde] +version = "0.8.*" +optional = true [dev-dependencies] serde_macros = "0.8.*" From e96a3645facac8f9f0d61aa83919c9dd27554d0f Mon Sep 17 00:00:00 2001 From: Brian Bowman Date: Tue, 20 Sep 2016 18:03:54 -0500 Subject: [PATCH 21/42] Fix typo in bincode::serde (#88) --- src/serde/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index e570111..b6a30d4 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -1,5 +1,5 @@ //! 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}; From 8d708cd194f0c8c460c47e43bed904eebddb7946 Mon Sep 17 00:00:00 2001 From: Nikita Baksalyar Date: Mon, 28 Nov 2016 02:08:20 +0500 Subject: [PATCH 22/42] Delegate emit_enum_struct_variant calls to emit_enum_variant (#89) * Delegate emit_enum_struct_variant calls to emit_enum_variant read_enum_struct_variant delegates calls to read_enum_variant which expects u32 prefix to encode a variant number. Previous implementation of emit_enum_struct_variant doesn't emit it, making serialized data invalid. * Add test to check manual enum encoding --- src/rustc_serialize/writer.rs | 8 +++--- tests/test.rs | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/rustc_serialize/writer.rs b/src/rustc_serialize/writer.rs index 04dd1e3..2ab8da4 100644 --- a/src/rustc_serialize/writer.rs +++ b/src/rustc_serialize/writer.rs @@ -176,14 +176,14 @@ impl<'a, W: Write> Encoder for EncoderWriter<'a, W> { f(self) } fn emit_enum_struct_variant(&mut self, - _: &str, - _: usize, - _: usize, + v_name: &str, + v_id: usize, + len: usize, f: F) -> EncodingResult<()> where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> { - f(self) + self.emit_enum_variant(v_name, v_id, len, f) } fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()> where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> diff --git a/tests/test.rs b/tests/test.rs index d114f64..976bb8f 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -515,3 +515,51 @@ fn path_buf() { let decoded: PathBuf = bincode::serde::deserialize(&serde_encoded).unwrap(); assert!(path.to_str() == decoded.to_str()); } + +#[test] +fn test_manual_enum_encoding() { + #[derive(PartialEq)] + enum Enumeration { + Variant1, + Variant2 { val: u64 } + } + + impl Encodable for Enumeration { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_enum("Enumeration", |s| { + match *self { + Enumeration::Variant1 => { + s.emit_enum_variant("Variant1", 0, 0, |_| Ok(())) + }, + Enumeration::Variant2 { val } => { + s.emit_enum_struct_variant("Variant2", 1, 1, |s| { + s.emit_enum_struct_variant_field("val", 0, |s| s.emit_u64(val)) + }) + } + } + }) + } + } + + impl Decodable for Enumeration { + fn decode(s: &mut D) -> Result { + s.read_enum("Enumeration", |s| { + s.read_enum_struct_variant(&["Variant1", "Variant2"], |s, num| { + match num { + 0 => Ok(Enumeration::Variant1), + 1 => Ok(Enumeration::Variant2 { val: try!(s.read_u64()) }), + _ => Err(s.error("Unknown enum variant")) + } + }) + }) + } + } + + let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant1, Infinite).unwrap(); + let decoded: Enumeration = decode(&encoded[..]).unwrap(); + assert!(decoded == Enumeration::Variant1); + + let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant2 { val: 42 }, Infinite).unwrap(); + let decoded: Enumeration = decode(&encoded[..]).unwrap(); + assert!(decoded == Enumeration::Variant2 { val: 42 }); +} From 3d4346808fba91f0121e72bb1d775b90d7c3fded Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 12 Dec 2016 13:26:26 -0500 Subject: [PATCH 23/42] More efficient serialize_bytes (#90) * Update to serde_derive * Fix missing Encoder and Decoder imports * Add test for serializing bytes * More efficient serialize_bytes Reported in #serde: blank_name2 tried serializing `HashMap>` vs `HashMap>`, the `&Path` version was done in ~.6 seconds while the `&[u8]` one took a full 3 seconds more. --- Cargo.toml | 2 +- src/serde/writer.rs | 14 ++++---------- tests/test.rs | 20 +++++++++++++++++--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c4befb7..bb54fd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ version = "0.8.*" optional = true [dev-dependencies] -serde_macros = "0.8.*" +serde_derive = "0.8.*" [features] default = ["rustc-serialize", "serde"] diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 0c3ae3c..58666eb 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -163,11 +163,8 @@ impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { } fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { - let mut state = try!(self.serialize_seq(Some(v.len()))); - for c in v { - try!(self.serialize_seq_elt(&mut state, c)); - } - self.serialize_seq_end(state) + try!(self.serialize_usize(v.len())); + self.writer.write_all(v).map_err(SerializeError::IoError) } fn serialize_none(&mut self) -> SerializeResult<()> { @@ -440,11 +437,8 @@ impl serde::Serializer for SizeChecker { } fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { - let mut state = try!(self.serialize_seq(Some(v.len()))); - for c in v { - try!(self.serialize_seq_elt(&mut state, c)); - } - self.serialize_seq_end(state) + try!(self.add_value(0 as u64)); + self.add_raw(v.len()) } fn serialize_none(&mut self) -> SerializeResult<()> { diff --git a/tests/test.rs b/tests/test.rs index 976bb8f..13c0dc1 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,5 +1,7 @@ -#![feature(plugin, custom_derive, custom_attribute)] -#![plugin(serde_macros)] +#![feature(proc_macro)] + +#[macro_use] +extern crate serde_derive; extern crate bincode; extern crate rustc_serialize; @@ -9,7 +11,7 @@ use std::fmt::Debug; use std::collections::HashMap; use std::ops::Deref; -use rustc_serialize::{Encodable, Decodable}; +use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use bincode::{RefBox, StrBox, SliceBox}; @@ -516,6 +518,18 @@ fn path_buf() { assert!(path.to_str() == decoded.to_str()); } +#[test] +fn bytes() { + let data = b"abc\0123"; + let b = bincode::rustc_serialize::encode(&data, Infinite).unwrap(); + let s = bincode::serde::serialize(&data, Infinite).unwrap(); + assert_eq!(b, s); + + use serde::bytes::Bytes; + let s2 = bincode::serde::serialize(&Bytes::new(data), Infinite).unwrap(); + assert_eq!(s, s2); +} + #[test] fn test_manual_enum_encoding() { #[derive(PartialEq)] From 814aa7d2399992d058803b8c7801fefe234a42a2 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 5 Jan 2017 17:25:40 -0800 Subject: [PATCH 24/42] Update to byteorder 1.0 (#91) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bb54fd8..b24d4c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT" description = "A binary serialization / deserialization strategy and implementation with serde and rustc-serialize backends." [dependencies] -byteorder = "0.5.*" +byteorder = "1.0.0" num-traits = "0.1.32" [dependencies.rustc-serialize] From 147a89f8d7d5b0efcef33833ca2d15d9235ae96b Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Thu, 5 Jan 2017 17:26:50 -0800 Subject: [PATCH 25/42] bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b24d4c7..3b8bdb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.6.0" +version = "0.6.1" authors = ["Ty Overby ", "Francesco Mazzoli "] repository = "https://github.com/TyOverby/bincode" From c6393ac56121a06da024683f1744e7aae40e587c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Tue, 31 Jan 2017 11:59:29 -0600 Subject: [PATCH 26/42] Update to serde 0.9.X (#93) * Update to serde 0.9.X * Remove redundant visitor and bad namespacing. * Change DeserializeError to use Strings. Reintroduce error tests. * Better DeserializeError messages. * Fix warnings. --- Cargo.toml | 4 +- src/refbox.rs | 16 +- src/serde/reader.rs | 245 +++++++--------- src/serde/writer.rs | 667 ++++++++++++++++++++++++++------------------ tests/test.rs | 6 +- 5 files changed, 509 insertions(+), 429 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b24d4c7..48eec29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,11 +19,11 @@ version = "0.3.*" optional = true [dependencies.serde] -version = "0.8.*" +version = "0.9.*" optional = true [dev-dependencies] -serde_derive = "0.8.*" +serde_derive = "0.9.*" [features] default = ["rustc-serialize", "serde"] diff --git a/src/refbox.rs b/src/refbox.rs index fb91124..addfa48 100644 --- a/src/refbox.rs +++ b/src/refbox.rs @@ -160,7 +160,7 @@ impl Decodable for RefBox<'static, T> { 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) @@ -169,7 +169,7 @@ impl<'a, T> serde::Serialize for RefBox<'a, T> #[cfg(feature = "serde")] impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let inner = try!(serde::Deserialize::deserialize(deserializer)); @@ -256,7 +256,7 @@ impl Decodable for StrBox<'static> { #[cfg(feature = "serde")] 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) @@ -265,7 +265,7 @@ impl<'a> serde::Serialize for StrBox<'a> { #[cfg(feature = "serde")] 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)); @@ -349,7 +349,7 @@ impl Decodable for SliceBox<'static, T> { 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) @@ -358,7 +358,7 @@ impl<'a, T> serde::Serialize for SliceBox<'a, T> #[cfg(feature = "serde")] impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer { let inner = try!(serde::Deserialize::deserialize(deserializer)); @@ -381,7 +381,7 @@ 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 { @@ -403,7 +403,7 @@ impl Decodable 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/serde/reader.rs b/src/serde/reader.rs index 00ea18c..1578a82 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -5,10 +5,9 @@ use std::fmt; use std::convert::From; use byteorder::{BigEndian, ReadBytesExt}; -use num_traits; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; - +use serde_crate::de::Error as DeError; use ::SizeLimit; #[derive(Eq, PartialEq, Clone, Debug)] @@ -45,7 +44,7 @@ pub enum DeserializeError { /// If decoding a message takes more than the provided size limit, this /// error is returned. SizeLimit, - Serde(serde::de::value::Error) + Custom(String) } impl Error for DeserializeError { @@ -54,7 +53,7 @@ impl Error for DeserializeError { 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(), + DeserializeError::Custom(ref msg) => msg, } } @@ -64,7 +63,7 @@ impl Error for DeserializeError { DeserializeError::IoError(ref err) => err.cause(), DeserializeError::InvalidEncoding(_) => None, DeserializeError::SizeLimit => None, - DeserializeError::Serde(ref s) => s.cause(), + DeserializeError::Custom(_) => None, } } } @@ -75,12 +74,6 @@ impl From for DeserializeError { } } -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 { @@ -90,19 +83,15 @@ impl fmt::Display for DeserializeError { write!(fmt, "InvalidEncoding: {}", ib), DeserializeError::SizeLimit => write!(fmt, "SizeLimit"), - DeserializeError::Serde(ref s) => + DeserializeError::Custom(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) + fn custom(desc: T) -> DeserializeError { + DeserializeError::Custom(desc.to_string()) } } @@ -119,14 +108,14 @@ 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 } -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, @@ -154,7 +143,7 @@ impl<'a, R: Read> Deserializer<'a, R> { } fn read_string(&mut self) -> DeserializeResult { - let len = try!(serde::Deserialize::deserialize(self)); + let len = try!(serde::Deserialize::deserialize(&mut *self)); try!(self.read_bytes(len)); let mut buffer = Vec::new(); @@ -171,7 +160,7 @@ impl<'a, R: Read> Deserializer<'a, R> { 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) -> DeserializeResult where V: serde::de::Visitor, { try!(self.read_type::<$ty>()); @@ -182,18 +171,18 @@ macro_rules! impl_nums { } -impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { +impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { type Error = DeserializeError; #[inline] - fn deserialize(&mut self, _visitor: V) -> DeserializeResult + fn deserialize(self, _visitor: V) -> DeserializeResult where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize"; - Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + Err(DeserializeError::custom(message)) } - fn deserialize_bool(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_bool(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { let value: u8 = try!(serde::Deserialize::deserialize(self)); @@ -220,7 +209,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) -> DeserializeResult where V: serde::de::Visitor, { try!(self.read_type::()); @@ -228,44 +217,20 @@ 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_traits::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) -> DeserializeResult 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_traits::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) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_unit() } - fn deserialize_char(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_char(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { use std::str; @@ -303,59 +268,74 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { visitor.visit_char(res) } - fn deserialize_str(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_str(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_str(&try!(self.read_string())) } - fn deserialize_string(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_string(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_string(try!(self.read_string())) } - fn deserialize_bytes(&mut self, visitor: V) -> DeserializeResult + fn deserialize_bytes(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { self.deserialize_seq(visitor) } - fn deserialize_enum(&mut 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 + fn deserialize_byte_buf(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { - struct TupleVisitor<'a, 'b: 'a, R: Read + 'b>(&'a mut Deserializer<'b, R>); + self.deserialize_seq(visitor) + } - impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, 'b, R> { + fn deserialize_enum(self, + _enum: &'static str, + _variants: &'static [&'static str], + visitor: V) -> Result + where V: serde::de::Visitor, + { + impl<'a, R: Read + 'a> serde::de::EnumVisitor for &'a mut Deserializer { + type Error = DeserializeError; + type Variant = Self; + + fn visit_variant_seed(self, seed: V) -> DeserializeResult<(V::Value, Self::Variant)> + where V: serde::de::DeserializeSeed, + { + let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self)); + let val: Result<_, DeserializeError> = seed.deserialize(idx.into_deserializer()); + Ok((try!(val), self)) + } + } + + visitor.visit_enum(self) + } + + fn deserialize_tuple(self, + _len: usize, + visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + struct TupleVisitor<'a, R: Read + 'a>(&'a mut Deserializer); + + impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, R> { type Error = DeserializeError; - fn visit(&mut self) -> Result, Self::Error> - where T: serde::de::Deserialize, + fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + where T: serde::de::DeserializeSeed, { - let value = try!(serde::Deserialize::deserialize(self.0)); + let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.0)); Ok(Some(value)) } - - fn end(&mut self) -> Result<(), Self::Error> { - Ok(()) - } } visitor.visit_seq(TupleVisitor(self)) } - fn deserialize_seq_fixed_size(&mut self, + fn deserialize_seq_fixed_size(self, _: usize, visitor: V) -> DeserializeResult where V: serde::de::Visitor, @@ -363,13 +343,13 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { self.deserialize_seq(visitor) } - fn deserialize_option(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_option(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { - let value: u8 = try!(serde::de::Deserialize::deserialize(self)); + let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); match value { 0 => visitor.visit_none(), - 1 => visitor.visit_some(self), + 1 => visitor.visit_some(&mut *self), _ => Err(DeserializeError::InvalidEncoding(InvalidEncoding { desc: "invalid tag when decoding Option", detail: Some(format!("Expected 0 or 1, got {}", value)) @@ -377,88 +357,72 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { } } - fn deserialize_seq(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_seq(self, 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> { + deserializer: &'a mut Deserializer, len: usize, } - impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, 'b, R> { + impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, R> { type Error = DeserializeError; - fn visit(&mut self) -> Result, Self::Error> - where T: serde::de::Deserialize, + fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + 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)); + let len = try!(serde::Deserialize::deserialize(&mut *self)); visitor.visit_seq(SeqVisitor { deserializer: self, len: len }) } - fn deserialize_map(&mut self, mut visitor: V) -> DeserializeResult + fn deserialize_map(self, visitor: V) -> DeserializeResult where V: serde::de::Visitor, { - struct MapVisitor<'a, 'b: 'a, R: Read + 'b> { - deserializer: &'a mut Deserializer<'b, R>, + struct MapVisitor<'a, R: Read + 'a> { + deserializer: &'a mut Deserializer, len: usize, } - impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, 'b, R> { + impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, R> { type Error = DeserializeError; - fn visit_key(&mut self) -> Result, Self::Error> - where K: serde::de::Deserialize, + fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> + 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 @@ -467,31 +431,31 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { self.deserialize_tuple(fields.len(), visitor) } - fn deserialize_struct_field(&mut self, + fn deserialize_struct_field(self, _visitor: V) -> DeserializeResult where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize_struct_field"; - Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + Err(DeserializeError::custom(message)) } - fn deserialize_newtype_struct(&mut self, + fn deserialize_newtype_struct(self, _name: &str, - mut visitor: V) -> DeserializeResult + visitor: V) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_newtype_struct(self) } - fn deserialize_unit_struct(&mut self, + fn deserialize_unit_struct(self, _name: &'static str, - mut visitor: V) -> DeserializeResult + visitor: V) -> DeserializeResult where V: serde::de::Visitor, { visitor.visit_unit() } - fn deserialize_tuple_struct(&mut self, + fn deserialize_tuple_struct(self, _name: &'static str, len: usize, visitor: V) -> DeserializeResult @@ -500,38 +464,29 @@ impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> { self.deserialize_tuple(len, visitor) } - fn deserialize_ignored_any(&mut self, + fn deserialize_ignored_any(self, _visitor: V) -> DeserializeResult where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize_ignored_any"; - Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into()))) + Err(DeserializeError::custom(message)) } } -impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> { +impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer { type Error = DeserializeError; - fn visit_variant(&mut self) -> Result - where V: serde::Deserialize, - { - 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)) - } - - fn visit_unit(&mut self) -> Result<(), Self::Error> { + fn visit_unit(self) -> Result<(), Self::Error> { 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 where V: serde::de::Visitor, @@ -539,7 +494,7 @@ impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> { serde::de::Deserializer::deserialize_tuple(self, len, visitor) } - fn visit_struct(&mut self, + fn visit_struct(self, fields: &'static [&'static str], visitor: V) -> Result where V: serde::de::Visitor, diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 58666eb..3b5aaa5 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -29,8 +29,8 @@ pub enum SerializeError { /// /// 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, } fn wrap_io(err: IoError) -> SerializeError { @@ -38,8 +38,8 @@ fn wrap_io(err: IoError) -> SerializeError { } impl serde::ser::Error for SerializeError { - fn custom>(msg: T) -> Self { - SerializeError::Custom(msg.into()) + fn custom(msg: T) -> Self { + SerializeError::Custom(msg.to_string()) } } @@ -71,8 +71,8 @@ impl Error for SerializeError { } } -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, } @@ -87,237 +87,158 @@ impl<'a, W: Write> Serializer<'a, W> { } } -impl<'a, W: Write> serde::Serializer for Serializer<'a, W> { +impl<'a, W: Write> serde::Serializer for &'a mut Serializer { + type Ok = (); type Error = SerializeError; - type SeqState = (); - type TupleState = (); - type TupleStructState = (); - type TupleVariantState = (); - type MapState = (); - type StructState = (); - type StructVariantState = (); + type SerializeSeq = Compound<'a, W>; + type SerializeTuple = Compound<'a, W>; + type SerializeTupleStruct = Compound<'a, W>; + type SerializeTupleVariant = Compound<'a, W>; + type SerializeMap = Compound<'a, W>; + type SerializeStruct = Compound<'a, W>; + type SerializeStructVariant = Compound<'a, W>; - fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit(self) -> SerializeResult<()> { Ok(()) } - fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(self, _: &'static str) -> SerializeResult<()> { Ok(()) } - fn serialize_bool(&mut self, v: bool) -> SerializeResult<()> { + fn serialize_bool(self, v: bool) -> SerializeResult<()> { self.writer.write_u8(if v {1} else {0}).map_err(wrap_io) } - fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> { + fn serialize_u8(self, v: u8) -> SerializeResult<()> { self.writer.write_u8(v).map_err(wrap_io) } - fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> { + fn serialize_u16(self, v: u16) -> SerializeResult<()> { self.writer.write_u16::(v).map_err(wrap_io) } - fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> { + fn serialize_u32(self, v: u32) -> SerializeResult<()> { self.writer.write_u32::(v).map_err(wrap_io) } - fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> { + fn serialize_u64(self, v: u64) -> SerializeResult<()> { self.writer.write_u64::(v).map_err(wrap_io) } - fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> { - self.serialize_u64(v as u64) - } - - fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { + fn serialize_i8(self, v: i8) -> SerializeResult<()> { self.writer.write_i8(v).map_err(wrap_io) } - fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> { + fn serialize_i16(self, v: i16) -> SerializeResult<()> { self.writer.write_i16::(v).map_err(wrap_io) } - fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> { + fn serialize_i32(self, v: i32) -> SerializeResult<()> { self.writer.write_i32::(v).map_err(wrap_io) } - fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> { + fn serialize_i64(self, v: i64) -> SerializeResult<()> { self.writer.write_i64::(v).map_err(wrap_io) } - fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> { - self.serialize_i64(v as i64) - } - - fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { + fn serialize_f32(self, v: f32) -> SerializeResult<()> { self.writer.write_f32::(v).map_err(wrap_io) } - fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> { + fn serialize_f64(self, v: f64) -> SerializeResult<()> { self.writer.write_f64::(v).map_err(wrap_io) } - fn serialize_str(&mut self, v: &str) -> SerializeResult<()> { - try!(self.serialize_usize(v.len())); + fn serialize_str(self, v: &str) -> SerializeResult<()> { + try!(self.serialize_u64(v.len() as u64)); self.writer.write_all(v.as_bytes()).map_err(SerializeError::IoError) } - fn serialize_char(&mut self, c: char) -> SerializeResult<()> { + fn serialize_char(self, c: char) -> SerializeResult<()> { self.writer.write_all(encode_utf8(c).as_slice()).map_err(SerializeError::IoError) } - fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { - try!(self.serialize_usize(v.len())); + fn serialize_bytes(self, v: &[u8]) -> SerializeResult<()> { + try!(self.serialize_u64(v.len() as u64)); self.writer.write_all(v).map_err(SerializeError::IoError) } - fn serialize_none(&mut self) -> SerializeResult<()> { + fn serialize_none(self) -> SerializeResult<()> { self.writer.write_u8(0).map_err(wrap_io) } - fn serialize_some(&mut self, v: T) -> SerializeResult<()> + fn serialize_some(self, v: &T) -> SerializeResult<()> where T: serde::Serialize, { try!(self.writer.write_u8(1).map_err(wrap_io)); v.serialize(self) } - fn serialize_seq(&mut self, len: Option) -> SerializeResult<()> { + fn serialize_seq(self, len: Option) -> SerializeResult { let len = len.expect("do not know how to serialize a sequence with no length"); - self.serialize_usize(len) + try!(self.serialize_u64(len as u64)); + Ok(Compound {ser: self}) } - fn serialize_seq_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> { + fn serialize_seq_fixed_size(self, len: usize) -> SerializeResult { self.serialize_seq(Some(len)) } - fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> { - Ok(()) + fn serialize_tuple(self, _len: usize) -> SerializeResult { + Ok(Compound {ser: self}) } - fn serialize_tuple_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + Ok(Compound {ser: self}) } - fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_struct_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_variant(&mut self, + fn serialize_tuple_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult<()> + _len: usize) -> SerializeResult { - self.add_enum_tag(variant_index) + try!(self.add_enum_tag(variant_index)); + Ok(Compound {ser: self}) } - fn serialize_tuple_variant_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_map(&mut self, len: Option) -> SerializeResult<()> { + fn serialize_map(self, len: Option) -> SerializeResult { let len = len.expect("do not know how to serialize a map with no length"); - self.serialize_usize(len) + try!(self.serialize_u64(len as u64)); + Ok(Compound {ser: self}) } - fn serialize_map_key(&mut self, _: &mut (), key: K) -> SerializeResult<()> - where K: serde::Serialize, - { - key.serialize(self) + fn serialize_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + Ok(Compound {ser: self}) } - fn serialize_map_value(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct_variant(&mut self, + fn serialize_struct_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult<()> + _len: usize) -> SerializeResult { - self.add_enum_tag(variant_index) + try!(self.add_enum_tag(variant_index)); + Ok(Compound {ser: self}) } - fn serialize_struct_variant_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_newtype_struct(&mut self, + fn serialize_newtype_struct(self, _name: &'static str, - value: T) -> SerializeResult<()> + value: &T) -> SerializeResult<()> where T: serde::ser::Serialize, { value.serialize(self) } - fn serialize_newtype_variant(&mut self, + fn serialize_newtype_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - value: T) -> SerializeResult<()> + value: &T) -> SerializeResult<()> where T: serde::ser::Serialize, { try!(self.add_enum_tag(variant_index)); value.serialize(self) } - fn serialize_unit_variant(&mut self, + fn serialize_unit_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str) -> SerializeResult<()> { @@ -361,242 +282,446 @@ impl SizeChecker { } } -impl serde::Serializer for SizeChecker { +impl<'a> serde::Serializer for &'a mut SizeChecker { + type Ok = (); type Error = SerializeError; - type SeqState = (); - type TupleState = (); - type TupleStructState = (); - type TupleVariantState = (); - type MapState = (); - type StructState = (); - type StructVariantState = (); + 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) -> SerializeResult<()> { Ok(()) } - fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(self, _: &'static str) -> SerializeResult<()> { Ok(()) } - fn serialize_bool(&mut self, _: bool) -> SerializeResult<()> { + fn serialize_bool(self, _: bool) -> SerializeResult<()> { self.add_value(0 as u8) } - fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> { + fn serialize_u8(self, v: u8) -> SerializeResult<()> { self.add_value(v) } - fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> { + fn serialize_u16(self, v: u16) -> SerializeResult<()> { self.add_value(v) } - fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> { + fn serialize_u32(self, v: u32) -> SerializeResult<()> { self.add_value(v) } - fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> { + fn serialize_u64(self, v: u64) -> SerializeResult<()> { self.add_value(v) } - fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> { - self.serialize_u64(v as u64) - } - - fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> { + fn serialize_i8(self, v: i8) -> SerializeResult<()> { self.add_value(v) } - fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> { + fn serialize_i16(self, v: i16) -> SerializeResult<()> { self.add_value(v) } - fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> { + fn serialize_i32(self, v: i32) -> SerializeResult<()> { self.add_value(v) } - fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> { + fn serialize_i64(self, v: i64) -> SerializeResult<()> { self.add_value(v) } - fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> { - self.serialize_i64(v as i64) - } - - fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> { + fn serialize_f32(self, v: f32) -> SerializeResult<()> { self.add_value(v) } - fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> { + fn serialize_f64(self, v: f64) -> SerializeResult<()> { self.add_value(v) } - fn serialize_str(&mut self, v: &str) -> SerializeResult<()> { + fn serialize_str(self, v: &str) -> SerializeResult<()> { try!(self.add_value(0 as u64)); self.add_raw(v.len()) } - fn serialize_char(&mut self, c: char) -> SerializeResult<()> { + fn serialize_char(self, c: char) -> SerializeResult<()> { self.add_raw(encode_utf8(c).as_slice().len()) } - fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> { + fn serialize_bytes(self, v: &[u8]) -> SerializeResult<()> { try!(self.add_value(0 as u64)); self.add_raw(v.len()) } - fn serialize_none(&mut self) -> SerializeResult<()> { + fn serialize_none(self) -> SerializeResult<()> { self.add_value(0 as u8) } - fn serialize_some(&mut self, v: T) -> SerializeResult<()> + fn serialize_some(self, v: &T) -> SerializeResult<()> where T: serde::Serialize, { try!(self.add_value(1 as u8)); v.serialize(self) } - fn serialize_seq(&mut self, len: Option) -> SerializeResult<()> { + fn serialize_seq(self, len: Option) -> SerializeResult { let len = len.expect("do not know how to serialize a sequence with no length"); - self.serialize_usize(len) + try!(self.serialize_u64(len as u64)); + Ok(SizeCompound {ser: self}) } - fn serialize_seq_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> { + fn serialize_seq_fixed_size(self, len: usize) -> SerializeResult { self.serialize_seq(Some(len)) } - fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> { - Ok(()) + fn serialize_tuple(self, _len: usize) -> SerializeResult { + Ok(SizeCompound {ser: self}) } - fn serialize_tuple_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + Ok(SizeCompound {ser: self}) } - fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_struct_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_tuple_variant(&mut self, + fn serialize_tuple_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult<()> + _len: usize) -> SerializeResult { - self.add_enum_tag(variant_index) + try!(self.add_enum_tag(variant_index)); + Ok(SizeCompound {ser: self}) } - fn serialize_tuple_variant_elt(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_map(&mut self, len: Option) -> SerializeResult<()> + fn serialize_map(self, len: Option) -> SerializeResult { let len = len.expect("do not know how to serialize a map with no length"); - self.serialize_usize(len) + try!(self.serialize_u64(len as u64)); + Ok(SizeCompound {ser: self}) } - fn serialize_map_key(&mut self, _: &mut (), key: K) -> SerializeResult<()> - where K: serde::Serialize, - { - key.serialize(self) + fn serialize_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + Ok(SizeCompound {ser: self}) } - fn serialize_map_value(&mut self, _: &mut (), value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct_elt(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_struct_variant(&mut self, + fn serialize_struct_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult<()> + _len: usize) -> SerializeResult { - self.add_enum_tag(variant_index) + try!(self.add_enum_tag(variant_index)); + Ok(SizeCompound {ser: self}) } - fn serialize_struct_variant_elt(&mut self, _: &mut (), _field: &'static str, value: V) -> SerializeResult<()> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> { - Ok(()) - } - - fn serialize_newtype_struct(&mut self, _name: &'static str, v: V) -> SerializeResult<()> { + fn serialize_newtype_struct(self, _name: &'static str, v: &V) -> SerializeResult<()> { v.serialize(self) } - fn serialize_unit_variant(&mut self, + fn serialize_unit_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str) -> SerializeResult<()> { self.add_enum_tag(variant_index) } - fn serialize_newtype_variant(&mut self, + fn serialize_newtype_variant(self, _name: &'static str, variant_index: usize, _variant: &'static str, - value: V) -> SerializeResult<()> + value: &V) -> SerializeResult<()> { try!(self.add_enum_tag(variant_index)); value.serialize(self) } } +#[doc(hidden)] +pub struct Compound<'a, W: 'a> { + ser: &'a mut Serializer, +} + +impl<'a, W> serde::ser::SerializeSeq for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeTuple for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeTupleStruct for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeTupleVariant for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeMap for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_key(&mut self, value: &K) -> SerializeResult<()> + where K: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> SerializeResult<()> + where V: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeStruct for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a, W> serde::ser::SerializeStructVariant for Compound<'a, W> + where W: Write +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +#[doc(hidden)] +pub struct SizeCompound<'a> { + ser: &'a mut SizeChecker, +} + +impl<'a> serde::ser::SerializeSeq for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTuple for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTupleStruct for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeTupleVariant for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeMap for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_key(&mut self, value: &K) -> SerializeResult<()> + where K: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> SerializeResult<()> + where V: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeStruct for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + +impl<'a> serde::ser::SerializeStructVariant for SizeCompound<'a> +{ + type Ok = (); + type Error = SerializeError; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + where T: serde::ser::Serialize + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> SerializeResult<()> { + Ok(()) + } +} + const TAG_CONT: u8 = 0b1000_0000; const TAG_TWO_B: u8 = 0b1100_0000; const TAG_THREE_B: u8 = 0b1110_0000; diff --git a/tests/test.rs b/tests/test.rs index 13c0dc1..1474820 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -182,7 +182,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, @@ -252,8 +252,8 @@ 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(_))) => {}, + Err(DeserializeError::Custom(ref s)) if s.contains("invalid encoding") => {}, + Err(DeserializeError::Custom(ref s)) if s.contains("invalid value") => {}, _ => panic!("Expecting InvalidEncoding, got {:?}", res), } } From ecb51cb8bd807d172d33e00f9dd0fed17e343292 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 31 Jan 2017 10:43:47 -0800 Subject: [PATCH 27/42] update authors and docs link --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 02829f2..7897165 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "bincode" version = "0.6.1" -authors = ["Ty Overby ", "Francesco Mazzoli "] +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" From ab3f627ca89cb929d38df1c737769ec65213ec17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Tue, 31 Jan 2017 13:21:07 -0600 Subject: [PATCH 28/42] Don't panic. (#96) --- src/serde/writer.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 3b5aaa5..437745c 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -5,6 +5,7 @@ use std::io::Write; use std::u32; use serde_crate as serde; +use serde_crate::ser::Error as SeError; use byteorder::{BigEndian, WriteBytesExt}; @@ -172,7 +173,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = len.expect("do not know how to serialize a sequence with no length"); + let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -200,7 +201,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_map(self, len: Option) -> SerializeResult { - let len = len.expect("do not know how to serialize a map with no length"); + let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -367,7 +368,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = len.expect("do not know how to serialize a sequence with no length"); + let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) @@ -397,7 +398,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { fn serialize_map(self, len: Option) -> SerializeResult { - let len = len.expect("do not know how to serialize a map with no length"); + let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) From e4ce955928ea025b5732e870aba65a4ffc3de0a1 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 31 Jan 2017 11:23:08 -0800 Subject: [PATCH 29/42] change error message --- src/serde/writer.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 437745c..1e33e0d 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -173,7 +173,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); + let len = try!(len.ok_or(SerializeError::custom("bincode can't serialize a sequence with no length"))); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -201,7 +201,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_map(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); + let len = try!(len.ok_or(SerializeError::custom("bincode can't serialize a map with no length"))); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -368,7 +368,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); + let len = try!(len.ok_or(SerializeError::custom("bincode can't serialize a sequence with no length"))); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) @@ -398,7 +398,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { fn serialize_map(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); + let len = try!(len.ok_or(SerializeError::custom("bincode can't serialize a map with no length"))); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) From 5bfd6888197acca8ec3510bd4ac4c41c56c9ad1a Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 31 Jan 2017 12:56:25 -0800 Subject: [PATCH 30/42] change error message (#97) * change error message * add InfiniteSequence case to SerializeError * Change name --- src/serde/writer.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/serde/writer.rs b/src/serde/writer.rs index 437745c..bc67990 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -5,7 +5,6 @@ use std::io::Write; use std::u32; use serde_crate as serde; -use serde_crate::ser::Error as SeError; use byteorder::{BigEndian, WriteBytesExt}; @@ -22,6 +21,7 @@ pub enum SerializeError { /// This error is returned before any bytes are written to the /// output `Writer`. SizeLimit, + SequenceMustHaveLength, /// A custom error message Custom(String) } @@ -49,6 +49,8 @@ impl fmt::Display for SerializeError { match *self { SerializeError::IoError(ref err) => write!(f, "IoError: {}", err), SerializeError::Custom(ref s) => write!(f, "Custom Error {}", s), + SerializeError::SequenceMustHaveLength => + write!(f, "Bincode can only encode sequences and maps that have a knowable size ahead of time."), SerializeError::SizeLimit => write!(f, "SizeLimit"), } } @@ -58,16 +60,18 @@ 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", + SerializeError::SequenceMustHaveLength => "bincode can't encode infinite sequences", + SerializeError::SizeLimit => "the size limit for decoding has been reached", } } fn cause(&self) -> Option<&Error> { match *self { SerializeError::IoError(ref err) => err.cause(), - SerializeError::SizeLimit => None, SerializeError::Custom(_) => None, + SerializeError::SizeLimit => None, + SerializeError::SequenceMustHaveLength => None, } } } @@ -173,7 +177,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); + let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -201,7 +205,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_map(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); + let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(Compound {ser: self}) } @@ -368,7 +372,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { } fn serialize_seq(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a sequence with no length"))); + let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) @@ -398,7 +402,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { fn serialize_map(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::custom("do not know how to serialize a map with no length"))); + let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) From e7a74aa6c289815535399aab5593d6a2584b1d24 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 31 Jan 2017 15:50:55 -0800 Subject: [PATCH 31/42] Remove rustc serialize support (#95) * Remove rustc_serialize support * Add changelist and bump version number for alpha * Move refbox and friends into own module * update changelog * update travis config * move serde functions out into global namespace --- .travis.yml | 2 - Cargo.toml | 10 +- changelist.org | 18 ++ examples/basic.rs | 6 +- src/lib.rs | 21 +- src/refbox.rs | 71 ------ src/rustc_serialize/mod.rs | 102 -------- src/rustc_serialize/reader.rs | 392 ------------------------------- src/rustc_serialize/writer.rs | 422 ---------------------------------- tests/test.rs | 238 +++---------------- 10 files changed, 61 insertions(+), 1221 deletions(-) create mode 100644 changelist.org delete mode 100644 src/rustc_serialize/mod.rs delete mode 100644 src/rustc_serialize/reader.rs delete mode 100644 src/rustc_serialize/writer.rs diff --git a/.travis.yml b/.travis.yml index 23b588e..b67e3bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,4 @@ install: script: - multirust default $CHANNEL - cargo build - - cargo build --no-default-features --features "rustc-serialize" - - cargo build --no-default-features --features "serde" - if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi diff --git a/Cargo.toml b/Cargo.toml index 7897165..f541343 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "0.6.1" +version = "1.0.0-alpha1" authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Daniel Griffen"] repository = "https://github.com/TyOverby/bincode" @@ -14,16 +14,8 @@ description = "A binary serialization / deserialization strategy and implementat byteorder = "1.0.0" num-traits = "0.1.32" -[dependencies.rustc-serialize] -version = "0.3.*" -optional = true - [dependencies.serde] version = "0.9.*" -optional = true [dev-dependencies] serde_derive = "0.9.*" - -[features] -default = ["rustc-serialize", "serde"] 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 138a9e0..c76e219 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,21 +36,14 @@ #![doc(html_logo_url = "./icon.png")] -#[cfg(feature = "rustc-serialize")] -extern crate rustc_serialize as rustc_serialize_crate; extern crate byteorder; extern crate num_traits; -#[cfg(feature = "serde")] extern crate serde as serde_crate; +pub mod refbox; +mod serde; -pub use refbox::{RefBox, StrBox, SliceBox}; - -mod refbox; -#[cfg(feature = "rustc-serialize")] -pub mod rustc_serialize; -#[cfg(feature = "serde")] -pub mod serde; +pub use serde::*; /// A limit on the amount of bytes that can be read or written. /// @@ -76,4 +68,3 @@ pub enum SizeLimit { Infinite, Bounded(u64) } - diff --git a/src/refbox.rs b/src/refbox.rs index addfa48..be663f9 100644 --- a/src/refbox.rs +++ b/src/refbox.rs @@ -1,10 +1,6 @@ use std::boxed::Box; use std::ops::Deref; -#[cfg(feature = "rustc-serialize")] -use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder}; - -#[cfg(feature = "serde")] use serde_crate as serde; /// A struct for encoding nested reference types. @@ -141,22 +137,6 @@ impl RefBox<'static, T> { } } -#[cfg(feature = "rustc-serialize")] -impl <'a, T: Encodable> Encodable for RefBox<'a, T> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} - -#[cfg(feature = "rustc-serialize")] -impl Decodable for RefBox<'static, T> { - fn decode(d: &mut D) -> Result, D::Error> { - let inner = try!(Decodable::decode(d)); - Ok(RefBox{inner: inner}) - } -} - -#[cfg(feature = "serde")] impl<'a, T> serde::Serialize for RefBox<'a, T> where T: serde::Serialize, { @@ -167,7 +147,6 @@ impl<'a, T> serde::Serialize for RefBox<'a, T> } } -#[cfg(feature = "serde")] impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer @@ -239,22 +218,7 @@ impl StrBox<'static> { } } -#[cfg(feature = "rustc-serialize")] -impl <'a> Encodable for StrBox<'a> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} -#[cfg(feature = "rustc-serialize")] -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}) - } -} - -#[cfg(feature = "serde")] impl<'a> serde::Serialize for StrBox<'a> { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer @@ -263,7 +227,6 @@ impl<'a> serde::Serialize for StrBox<'a> { } } -#[cfg(feature = "serde")] impl serde::Deserialize for StrBox<'static> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer @@ -330,22 +293,7 @@ impl SliceBox<'static, T> { } } -#[cfg(feature = "rustc-serialize")] -impl <'a, T: Encodable> Encodable for SliceBox<'a, T> { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.inner.encode(s) - } -} -#[cfg(feature = "rustc-serialize")] -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}) - } -} - -#[cfg(feature = "serde")] impl<'a, T> serde::Serialize for SliceBox<'a, T> where T: serde::Serialize, { @@ -356,7 +304,6 @@ impl<'a, T> serde::Serialize for SliceBox<'a, T> } } -#[cfg(feature = "serde")] impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer @@ -366,17 +313,7 @@ impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> { } } -#[cfg(feature = "rustc-serialize")] -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) - } - } -} -#[cfg(feature = "serde")] impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> where A: serde::Serialize, B: serde::Serialize, @@ -391,15 +328,7 @@ impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B> } } -#[cfg(feature = "rustc-serialize")] -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)) - } -} -#[cfg(feature = "serde")] impl<'a, A: ?Sized, B> serde::Deserialize for RefBoxInner<'a, A, B> where B: serde::Deserialize, { diff --git a/src/rustc_serialize/mod.rs b/src/rustc_serialize/mod.rs deleted file mode 100644 index 2b75e80..0000000 --- a/src/rustc_serialize/mod.rs +++ /dev/null @@ -1,102 +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, InvalidEncoding}; - -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 ba1fd31..0000000 --- a/src/rustc_serialize/reader.rs +++ /dev/null @@ -1,392 +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 ::SizeLimit; - -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct InvalidEncoding { - pub desc: &'static str, - pub 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: IoError) -> DecodingError { - DecodingError::IoError(err) -} - -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 = match self.read.checked_add(count) { - Some(read) => read, - None => return Err(DecodingError::SizeLimit), - }; - 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 2ab8da4..0000000 --- a/src/rustc_serialize/writer.rs +++ /dev/null @@ -1,422 +0,0 @@ -use std::io::Write; -use std::io::Error as IoError; -use std::error::Error; -use std::fmt; - -use rustc_serialize_crate::Encoder; - -use byteorder::{BigEndian, WriteBytesExt}; - -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: IoError) -> EncodingError { - EncodingError::IoError(err) -} - -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, - v_name: &str, - v_id: usize, - len: usize, - f: F) - -> EncodingResult<()> - where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()> - { - self.emit_enum_variant(v_name, v_id, len, f) - } - 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/tests/test.rs b/tests/test.rs index 1474820..a9dd09f 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -4,61 +4,48 @@ extern crate serde_derive; extern crate bincode; -extern crate rustc_serialize; extern crate serde; use std::fmt::Debug; use std::collections::HashMap; use std::ops::Deref; -use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; - -use bincode::{RefBox, StrBox, SliceBox}; +use bincode::refbox::{RefBox, StrBox, SliceBox}; use bincode::SizeLimit::{self, Infinite, Bounded}; -use bincode::rustc_serialize::{encode, decode, decode_from, DecodingError}; -use bincode::serde::{serialize, deserialize, deserialize_from, DeserializeError, DeserializeResult}; +use bincode::{serialize, serialized_size, 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 + where V: 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 + let v2 = serialize(element, size_limit).unwrap(); + v2 } fn proxy_decode(slice: &[u8]) -> V - where V: Encodable + Decodable + serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static + where V: 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 + let e2 = deserialize(slice).unwrap(); + e2 } fn proxy_encoded_size(element: &V) -> u64 - where V: Encodable + serde::Serialize + PartialEq + Debug + 'static + where V: 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 + let serde_size = serialized_size(element); + serde_size } 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(&rf, Infinite).unwrap(); + let decoded: RefBox<'static, V> = deserialize(&encoded[..]).unwrap(); decoded.take().deref() == v } @@ -116,7 +103,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, @@ -127,13 +114,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, @@ -149,7 +136,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)); @@ -157,7 +144,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)); @@ -172,7 +159,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), @@ -224,29 +211,6 @@ fn test_fixed_size_array() { the_same([0u8; 19]); } -#[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][..])); -} - #[test] fn deserializing_errors() { fn isize_invalid_deserialize(res: DeserializeResult) { @@ -261,7 +225,7 @@ fn deserializing_errors() { isize_invalid_deserialize(deserialize::(&vec![0xA][..])); isize_invalid_deserialize(deserialize::(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..])); // Out-of-bounds variant - #[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug)] enum Test { One, Two, @@ -270,17 +234,6 @@ fn deserializing_errors() { 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()); -} - #[test] fn too_big_deserialize() { let serialized = vec![0,0,0,3]; @@ -302,14 +255,6 @@ fn char_serialization() { } } -#[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'); -} - #[test] fn too_big_char_deserialize() { let serialized = vec![0x41]; @@ -318,15 +263,6 @@ fn too_big_char_deserialize() { 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()); @@ -370,42 +306,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]; @@ -413,7 +313,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>) @@ -442,15 +342,6 @@ 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"; @@ -460,19 +351,6 @@ fn test_strbox_serialize() { 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]; @@ -486,20 +364,15 @@ 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()); } +/* #[test] fn test_oom_protection() { use std::io::Cursor; - #[derive(RustcEncodable, RustcDecodable)] struct FakeVec { len: u64, byte: u8 @@ -507,73 +380,24 @@ fn test_oom_protection() { 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(&path, Infinite).unwrap(); + let decoded: PathBuf = deserialize(&serde_encoded).unwrap(); assert!(path.to_str() == decoded.to_str()); } #[test] fn bytes() { - let data = b"abc\0123"; - let b = bincode::rustc_serialize::encode(&data, Infinite).unwrap(); - let s = bincode::serde::serialize(&data, Infinite).unwrap(); - assert_eq!(b, s); - use serde::bytes::Bytes; - let s2 = bincode::serde::serialize(&Bytes::new(data), Infinite).unwrap(); + + let data = b"abc\0123"; + let s = serialize(&data, Infinite).unwrap(); + let s2 = serialize(&Bytes::new(data), Infinite).unwrap(); assert_eq!(s, s2); } -#[test] -fn test_manual_enum_encoding() { - #[derive(PartialEq)] - enum Enumeration { - Variant1, - Variant2 { val: u64 } - } - - impl Encodable for Enumeration { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_enum("Enumeration", |s| { - match *self { - Enumeration::Variant1 => { - s.emit_enum_variant("Variant1", 0, 0, |_| Ok(())) - }, - Enumeration::Variant2 { val } => { - s.emit_enum_struct_variant("Variant2", 1, 1, |s| { - s.emit_enum_struct_variant_field("val", 0, |s| s.emit_u64(val)) - }) - } - } - }) - } - } - - impl Decodable for Enumeration { - fn decode(s: &mut D) -> Result { - s.read_enum("Enumeration", |s| { - s.read_enum_struct_variant(&["Variant1", "Variant2"], |s, num| { - match num { - 0 => Ok(Enumeration::Variant1), - 1 => Ok(Enumeration::Variant2 { val: try!(s.read_u64()) }), - _ => Err(s.error("Unknown enum variant")) - } - }) - }) - } - } - - let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant1, Infinite).unwrap(); - let decoded: Enumeration = decode(&encoded[..]).unwrap(); - assert!(decoded == Enumeration::Variant1); - - let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant2 { val: 42 }, Infinite).unwrap(); - let decoded: Enumeration = decode(&encoded[..]).unwrap(); - assert!(decoded == Enumeration::Variant2 { val: 42 }); -} From fac69cfcaaf46ca723b2ccd634e94a73995b426b Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Tue, 31 Jan 2017 20:20:26 -0800 Subject: [PATCH 32/42] Remove rustc-serialize from cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f541343..a5f344f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ documentation = "https://docs.rs/bincode" keywords = ["binary", "encode", "decode", "serialize", "deserialize"] license = "MIT" -description = "A binary serialization / deserialization strategy and implementation with serde and rustc-serialize backends." +description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!" [dependencies] byteorder = "1.0.0" From 419411d0042d29fb0d49578ccc6957b9cbab4aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Tue, 31 Jan 2017 22:24:08 -0600 Subject: [PATCH 33/42] Remove sized bounds where appropriate (#101) * Remove sized bounds where appropriate * Make bounds compatible with stable --- src/serde/mod.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index b6a30d4..102a051 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -33,8 +33,9 @@ mod writer; /// If this returns an `SerializeError` (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) -> SerializeResult<()> + where W: Write, + T: serde::Serialize, { match size_limit { SizeLimit::Infinite => { } @@ -52,8 +53,8 @@ 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) -> SerializeResult> + 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* @@ -77,7 +78,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(); @@ -89,7 +92,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) } @@ -103,7 +108,7 @@ pub fn serialized_size_bounded(value: &T, max: u64) -> Opti /// If this returns an `DeserializeError`, 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) -> DeserializeResult where R: Read, T: serde::Deserialize, { From 565b9c9f41e9b3c72dae4fa8c44b9ed7cd06c251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Fri, 3 Feb 2017 11:27:03 -0600 Subject: [PATCH 34/42] Remove length encoding (#102) * Remove length encoding * Improve bytes() test. --- src/serde/reader.rs | 44 ++++++++++++++++++++++---------------------- src/serde/writer.rs | 8 ++++---- tests/test.rs | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/serde/reader.rs b/src/serde/reader.rs index 1578a82..b177805 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -336,29 +336,9 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } fn deserialize_seq_fixed_size(self, - _: usize, + len: usize, visitor: V) -> DeserializeResult where V: serde::de::Visitor, - { - self.deserialize_seq(visitor) - } - - fn deserialize_option(self, visitor: V) -> DeserializeResult - where V: serde::de::Visitor, - { - let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); - match value { - 0 => visitor.visit_none(), - 1 => visitor.visit_some(&mut *self), - _ => Err(DeserializeError::InvalidEncoding(InvalidEncoding { - desc: "invalid tag when decoding Option", - detail: Some(format!("Expected 0 or 1, got {}", value)) - })), - } - } - - fn deserialize_seq(self, visitor: V) -> DeserializeResult - where V: serde::de::Visitor, { struct SeqVisitor<'a, R: Read + 'a> { deserializer: &'a mut Deserializer, @@ -381,9 +361,29 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } } + visitor.visit_seq(SeqVisitor { deserializer: self, len: len }) + } + + fn deserialize_option(self, visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { + let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); + match value { + 0 => visitor.visit_none(), + 1 => visitor.visit_some(&mut *self), + _ => Err(DeserializeError::InvalidEncoding(InvalidEncoding { + desc: "invalid tag when decoding Option", + detail: Some(format!("Expected 0 or 1, got {}", value)) + })), + } + } + + fn deserialize_seq(self, visitor: V) -> DeserializeResult + where V: serde::de::Visitor, + { let len = try!(serde::Deserialize::deserialize(&mut *self)); - visitor.visit_seq(SeqVisitor { deserializer: self, len: len }) + self.deserialize_seq_fixed_size(len, visitor) } fn deserialize_map(self, visitor: V) -> DeserializeResult diff --git a/src/serde/writer.rs b/src/serde/writer.rs index bc67990..75af352 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -182,8 +182,8 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { Ok(Compound {ser: self}) } - fn serialize_seq_fixed_size(self, len: usize) -> SerializeResult { - self.serialize_seq(Some(len)) + fn serialize_seq_fixed_size(self, _len: usize) -> SerializeResult { + Ok(Compound {ser: self}) } fn serialize_tuple(self, _len: usize) -> SerializeResult { @@ -378,8 +378,8 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { Ok(SizeCompound {ser: self}) } - fn serialize_seq_fixed_size(self, len: usize) -> SerializeResult { - self.serialize_seq(Some(len)) + fn serialize_seq_fixed_size(self, _len: usize) -> SerializeResult { + Ok(SizeCompound {ser: self}) } fn serialize_tuple(self, _len: usize) -> SerializeResult { diff --git a/tests/test.rs b/tests/test.rs index a9dd09f..5e0abb7 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -398,6 +398,6 @@ fn bytes() { let data = b"abc\0123"; let s = serialize(&data, Infinite).unwrap(); let s2 = serialize(&Bytes::new(data), Infinite).unwrap(); - assert_eq!(s, s2); + assert_eq!(s[..], s2[8..]); } From 19538cff29199edc66c7c8a72e38f747da47ea21 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Fri, 3 Feb 2017 09:54:39 -0800 Subject: [PATCH 35/42] Run tests on all channels (#108) * Run tests on all channels * try using travis.ci rust support --- .travis.yml | 32 +++++--------------------------- tests/test.rs | 2 -- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index b67e3bf..35b04d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,5 @@ -lang: c -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: - matrix: - - CHANNEL='stable' - - CHANNEL='beta' - - CHANNEL='nightly' - global: - - secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI= - -install: - - curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh > ./rustup.sh - - chmod +x ./rustup.sh - - ./rustup.sh --yes - -script: - - multirust default $CHANNEL - - cargo build - - if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi +language: rust +rust: + - stable + - beta + - nightly diff --git a/tests/test.rs b/tests/test.rs index 5e0abb7..dd13c9d 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,5 +1,3 @@ -#![feature(proc_macro)] - #[macro_use] extern crate serde_derive; From ffbe4387dd50f95a2380f8f74ff1f6d7d28d9ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Fri, 10 Feb 2017 01:07:20 -0600 Subject: [PATCH 36/42] Combine error types (#104) * Combine error types * Correct errors from merge conflict * Create ErrorKind and Box it up * Fix merge errors. * Fix merge errors re-adding length encoding. --- src/serde/mod.rs | 124 ++++++++++++++--- src/serde/reader.rs | 201 ++++++++------------------- src/serde/writer.rs | 321 ++++++++++++++++++-------------------------- tests/test.rs | 20 +-- 4 files changed, 304 insertions(+), 362 deletions(-) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 102a051..48f99b4 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -3,19 +3,16 @@ //! implementation. use std::io::{Write, Read}; +use std::io::Error as IoError; +use std::{error, fmt, result}; use ::SizeLimit; pub use self::reader::{ Deserializer, - DeserializeResult, - DeserializeError, - InvalidEncoding }; pub use self::writer::{ Serializer, - SerializeResult, - SerializeError, }; use self::writer::SizeChecker; @@ -25,15 +22,115 @@ 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(InvalidEncoding), + /// 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(ref ib) => ib.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(ref ib) => + write!(fmt, "InvalidEncoding: {}", ib), + 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() + } +} + +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct InvalidEncoding { + pub desc: &'static str, + pub 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) + } + } +} + /// 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<()> +pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> Result<()> where W: Write, T: serde::Serialize, { @@ -53,7 +150,7 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limi /// /// 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> +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 @@ -61,10 +158,7 @@ pub fn serialize(value: &T, size_limit: SizeLimit) -> SerializeResult // 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() @@ -105,10 +199,10 @@ pub fn serialized_size_bounded(value: &T, max: u64) -> Option /// 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, { @@ -120,7 +214,7 @@ pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> /// /// 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; diff --git a/src/serde/reader.rs b/src/serde/reader.rs index b177805..e563202 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -1,102 +1,11 @@ use std::io::Read; -use std::io::Error as IoError; -use std::error::Error; -use std::fmt; -use std::convert::From; use byteorder::{BigEndian, ReadBytesExt}; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; use serde_crate::de::Error as DeError; use ::SizeLimit; - -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct InvalidEncoding { - pub desc: &'static str, - pub 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, - Custom(String) -} - -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::Custom(ref msg) => msg, - - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - DeserializeError::IoError(ref err) => err.cause(), - DeserializeError::InvalidEncoding(_) => None, - DeserializeError::SizeLimit => None, - DeserializeError::Custom(_) => None, - } - } -} - -impl From for DeserializeError { - fn from(err: IoError) -> DeserializeError { - DeserializeError::IoError(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::Custom(ref s) => - s.fmt(fmt), - } - } -} - -impl serde::de::Error for DeserializeError { - fn custom(desc: T) -> DeserializeError { - DeserializeError::Custom(desc.to_string()) - } -} - -pub type DeserializeResult = Result; - +use super::{Result, Error, ErrorKind, InvalidEncoding}; /// A Deserializer that reads bytes from a buffer. /// @@ -128,21 +37,21 @@ impl Deserializer { self.read } - 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_string(&mut self) -> DeserializeResult { + fn read_string(&mut self) -> Result { let len = try!(serde::Deserialize::deserialize(&mut *self)); try!(self.read_bytes(len)); @@ -150,17 +59,17 @@ impl Deserializer { try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer)); String::from_utf8(buffer).map_err(|err| - DeserializeError::InvalidEncoding(InvalidEncoding { + ErrorKind::InvalidEncoding(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(self, visitor: V) -> DeserializeResult + fn $dser_method(self, visitor: V) -> Result where V: serde::de::Visitor, { try!(self.read_type::<$ty>()); @@ -172,17 +81,17 @@ macro_rules! impl_nums { impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { - type Error = DeserializeError; + type Error = Error; #[inline] - fn deserialize(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::custom(message)) + Err(Error::custom(message)) } - fn deserialize_bool(self, visitor: V) -> DeserializeResult + fn deserialize_bool(self, visitor: V) -> Result where V: serde::de::Visitor, { let value: u8 = try!(serde::Deserialize::deserialize(self)); @@ -190,10 +99,10 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { 1 => visitor.visit_bool(true), 0 => visitor.visit_bool(false), value => { - Err(DeserializeError::InvalidEncoding(InvalidEncoding { + Err(ErrorKind::InvalidEncoding(InvalidEncoding { desc: "invalid u8 when decoding bool", detail: Some(format!("Expected 0 or 1, got {}", value)) - })) + }).into()) } } } @@ -209,7 +118,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { #[inline] - fn deserialize_u8(self, visitor: V) -> DeserializeResult + fn deserialize_u8(self, visitor: V) -> Result where V: serde::de::Visitor, { try!(self.read_type::()); @@ -217,28 +126,28 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } #[inline] - fn deserialize_i8(self, 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())) } - fn deserialize_unit(self, visitor: V) -> DeserializeResult + fn deserialize_unit(self, visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_unit() } - fn deserialize_char(self, 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(InvalidEncoding { desc: "Invalid char encoding", detail: None - }); + }).into(); let mut buf = [0]; @@ -268,25 +177,25 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { visitor.visit_char(res) } - fn deserialize_str(self, visitor: V) -> DeserializeResult + fn deserialize_str(self, visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_str(&try!(self.read_string())) } - fn deserialize_string(self, visitor: V) -> DeserializeResult + 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) -> DeserializeResult + fn deserialize_bytes(self, visitor: V) -> Result where V: serde::de::Visitor, { self.deserialize_seq(visitor) } - fn deserialize_byte_buf(self, visitor: V) -> DeserializeResult + fn deserialize_byte_buf(self, visitor: V) -> Result where V: serde::de::Visitor, { self.deserialize_seq(visitor) @@ -295,18 +204,18 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_enum(self, _enum: &'static str, _variants: &'static [&'static str], - visitor: V) -> Result + visitor: V) -> Result where V: serde::de::Visitor, { impl<'a, R: Read + 'a> serde::de::EnumVisitor for &'a mut Deserializer { - type Error = DeserializeError; + type Error = Error; type Variant = Self; - fn visit_variant_seed(self, seed: V) -> DeserializeResult<(V::Value, Self::Variant)> + fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> where V: serde::de::DeserializeSeed, { let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self)); - let val: Result<_, DeserializeError> = seed.deserialize(idx.into_deserializer()); + let val: Result<_> = seed.deserialize(idx.into_deserializer()); Ok((try!(val), self)) } } @@ -316,15 +225,15 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_tuple(self, _len: usize, - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { struct TupleVisitor<'a, R: Read + 'a>(&'a mut Deserializer); impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, R> { - type Error = DeserializeError; + type Error = Error; - fn visit_seed(&mut self, seed: T) -> Result, Self::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)); @@ -337,7 +246,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_seq_fixed_size(self, len: usize, - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { struct SeqVisitor<'a, R: Read + 'a> { @@ -346,9 +255,9 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, R> { - type Error = DeserializeError; + type Error = Error; - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + fn visit_seed(&mut self, seed: T) -> Result> where T: serde::de::DeserializeSeed, { if self.len > 0 { @@ -364,21 +273,21 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { visitor.visit_seq(SeqVisitor { deserializer: self, len: len }) } - fn deserialize_option(self, visitor: V) -> DeserializeResult + fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor, { let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); match value { 0 => visitor.visit_none(), 1 => visitor.visit_some(&mut *self), - _ => Err(DeserializeError::InvalidEncoding(InvalidEncoding { + _ => Err(ErrorKind::InvalidEncoding(InvalidEncoding { desc: "invalid tag when decoding Option", detail: Some(format!("Expected 0 or 1, got {}", value)) - })), + }).into()), } } - fn deserialize_seq(self, visitor: V) -> DeserializeResult + fn deserialize_seq(self, visitor: V) -> Result where V: serde::de::Visitor, { let len = try!(serde::Deserialize::deserialize(&mut *self)); @@ -386,7 +295,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { self.deserialize_seq_fixed_size(len, visitor) } - fn deserialize_map(self, visitor: V) -> DeserializeResult + fn deserialize_map(self, visitor: V) -> Result where V: serde::de::Visitor, { struct MapVisitor<'a, R: Read + 'a> { @@ -395,9 +304,9 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, R> { - type Error = DeserializeError; + type Error = Error; - fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> + fn visit_key_seed(&mut self, seed: K) -> Result> where K: serde::de::DeserializeSeed, { if self.len > 0 { @@ -409,7 +318,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } } - fn visit_value_seed(&mut self, seed: V) -> Result + fn visit_value_seed(&mut self, seed: V) -> Result where V: serde::de::DeserializeSeed, { let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)); @@ -425,23 +334,23 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { 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_struct_field(self, - _visitor: V) -> DeserializeResult + _visitor: V) -> Result where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize_struct_field"; - Err(DeserializeError::custom(message)) + Err(Error::custom(message)) } fn deserialize_newtype_struct(self, _name: &str, - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_newtype_struct(self) @@ -449,7 +358,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_unit_struct(self, _name: &'static str, - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { visitor.visit_unit() @@ -458,29 +367,29 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_tuple_struct(self, _name: &'static str, len: usize, - visitor: V) -> DeserializeResult + visitor: V) -> Result where V: serde::de::Visitor, { self.deserialize_tuple(len, visitor) } fn deserialize_ignored_any(self, - _visitor: V) -> DeserializeResult + _visitor: V) -> Result where V: serde::de::Visitor, { let message = "bincode does not support Deserializer::deserialize_ignored_any"; - Err(DeserializeError::custom(message)) + Err(Error::custom(message)) } } impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer { - type Error = DeserializeError; + type Error = Error; - fn visit_unit(self) -> Result<(), Self::Error> { + fn visit_unit(self) -> Result<()> { Ok(()) } - fn visit_newtype_seed(self, seed: T) -> Result + fn visit_newtype_seed(self, seed: T) -> Result where T: serde::de::DeserializeSeed, { serde::de::DeserializeSeed::deserialize(seed, self) @@ -488,7 +397,7 @@ impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer { 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) @@ -496,7 +405,7 @@ impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer { 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 75af352..b44a6bf 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -1,6 +1,3 @@ -use std::error::Error; -use std::fmt; -use std::io::Error as IoError; use std::io::Write; use std::u32; @@ -8,23 +5,7 @@ use serde_crate as serde; use byteorder::{BigEndian, WriteBytesExt}; -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, - SequenceMustHaveLength, - /// A custom error message - Custom(String) -} +use super::{Result, Error, ErrorKind}; /// An Serializer that encodes values directly into a Writer. /// @@ -34,48 +15,6 @@ pub struct Serializer { writer: W, } -fn wrap_io(err: IoError) -> SerializeError { - SerializeError::IoError(err) -} - -impl serde::ser::Error for SerializeError { - fn custom(msg: T) -> Self { - SerializeError::Custom(msg.to_string()) - } -} - -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::SequenceMustHaveLength => - write!(f, "Bincode can only encode sequences and maps that have a knowable size ahead of time."), - SerializeError::SizeLimit => write!(f, "SizeLimit"), - } - } -} - -impl Error for SerializeError { - fn description(&self) -> &str { - match *self { - SerializeError::IoError(ref err) => Error::description(err), - SerializeError::Custom(_) => "a custom serialization error was reported", - SerializeError::SequenceMustHaveLength => "bincode can't encode infinite sequences", - SerializeError::SizeLimit => "the size limit for decoding has been reached", - } - } - - fn cause(&self) -> Option<&Error> { - match *self { - SerializeError::IoError(ref err) => err.cause(), - SerializeError::Custom(_) => None, - SerializeError::SizeLimit => None, - SerializeError::SequenceMustHaveLength => None, - } - } -} - impl Serializer { pub fn new(w: W) -> Serializer { Serializer { @@ -83,7 +22,7 @@ impl Serializer { } } - 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,7 +33,7 @@ impl Serializer { impl<'a, W: Write> serde::Serializer for &'a mut Serializer { type Ok = (); - type Error = SerializeError; + type Error = Error; type SerializeSeq = Compound<'a, W>; type SerializeTuple = Compound<'a, W>; type SerializeTupleStruct = Compound<'a, W>; @@ -103,94 +42,94 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { type SerializeStruct = Compound<'a, W>; type SerializeStructVariant = Compound<'a, W>; - fn serialize_unit(self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit(self) -> Result<()> { Ok(()) } - fn serialize_unit_struct(self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) } - fn serialize_bool(self, v: bool) -> SerializeResult<()> { - self.writer.write_u8(if v {1} else {0}).map_err(wrap_io) + fn serialize_bool(self, v: bool) -> Result<()> { + self.writer.write_u8(if v {1} else {0}).map_err(Into::into) } - fn serialize_u8(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(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(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(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(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(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(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(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(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(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(self, v: &str) -> SerializeResult<()> { + fn serialize_str(self, v: &str) -> Result<()> { try!(self.serialize_u64(v.len() as u64)); - self.writer.write_all(v.as_bytes()).map_err(SerializeError::IoError) + self.writer.write_all(v.as_bytes()).map_err(Into::into) } - fn serialize_char(self, c: char) -> SerializeResult<()> { - self.writer.write_all(encode_utf8(c).as_slice()).map_err(SerializeError::IoError) + fn serialize_char(self, c: char) -> Result<()> { + self.writer.write_all(encode_utf8(c).as_slice()).map_err(Into::into) } - fn serialize_bytes(self, v: &[u8]) -> SerializeResult<()> { + fn serialize_bytes(self, v: &[u8]) -> Result<()> { try!(self.serialize_u64(v.len() as u64)); - self.writer.write_all(v).map_err(SerializeError::IoError) + self.writer.write_all(v).map_err(Into::into) } - fn serialize_none(self) -> SerializeResult<()> { - self.writer.write_u8(0).map_err(wrap_io) + fn serialize_none(self) -> Result<()> { + self.writer.write_u8(0).map_err(Into::into) } - fn serialize_some(self, v: &T) -> SerializeResult<()> + 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(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); + 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_seq_fixed_size(self, _len: usize) -> SerializeResult { + fn serialize_seq_fixed_size(self, _len: usize) -> Result { Ok(Compound {ser: self}) } - fn serialize_tuple(self, _len: usize) -> SerializeResult { + fn serialize_tuple(self, _len: usize) -> Result { Ok(Compound {ser: self}) } - fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { Ok(Compound {ser: self}) } @@ -198,19 +137,19 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult + _len: usize) -> Result { try!(self.add_enum_tag(variant_index)); Ok(Compound {ser: self}) } - fn serialize_map(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); + 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(self, _name: &'static str, _len: usize) -> SerializeResult { + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Ok(Compound {ser: self}) } @@ -218,7 +157,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult + _len: usize) -> Result { try!(self.add_enum_tag(variant_index)); Ok(Compound {ser: self}) @@ -226,7 +165,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { fn serialize_newtype_struct(self, _name: &'static str, - value: &T) -> SerializeResult<()> + value: &T) -> Result<()> where T: serde::ser::Serialize, { value.serialize(self) @@ -236,7 +175,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { _name: &'static str, variant_index: usize, _variant: &'static str, - value: &T) -> SerializeResult<()> + value: &T) -> Result<()> where T: serde::ser::Serialize, { try!(self.add_enum_tag(variant_index)); @@ -246,7 +185,7 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { fn serialize_unit_variant(self, _name: &'static str, variant_index: usize, - _variant: &'static str) -> SerializeResult<()> { + _variant: &'static str) -> Result<()> { self.add_enum_tag(variant_index) } } @@ -264,21 +203,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") } @@ -289,7 +228,7 @@ impl SizeChecker { impl<'a> serde::Serializer for &'a mut SizeChecker { type Ok = (); - type Error = SerializeError; + type Error = Error; type SerializeSeq = SizeCompound<'a>; type SerializeTuple = SizeCompound<'a>; type SerializeTupleStruct = SizeCompound<'a>; @@ -298,95 +237,95 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { type SerializeStruct = SizeCompound<'a>; type SerializeStructVariant = SizeCompound<'a>; - fn serialize_unit(self) -> SerializeResult<()> { Ok(()) } + fn serialize_unit(self) -> Result<()> { Ok(()) } - fn serialize_unit_struct(self, _: &'static str) -> SerializeResult<()> { Ok(()) } + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) } - fn serialize_bool(self, _: bool) -> SerializeResult<()> { + fn serialize_bool(self, _: bool) -> Result<()> { self.add_value(0 as u8) } - fn serialize_u8(self, v: u8) -> SerializeResult<()> { + fn serialize_u8(self, v: u8) -> Result<()> { self.add_value(v) } - fn serialize_u16(self, v: u16) -> SerializeResult<()> { + fn serialize_u16(self, v: u16) -> Result<()> { self.add_value(v) } - fn serialize_u32(self, v: u32) -> SerializeResult<()> { + fn serialize_u32(self, v: u32) -> Result<()> { self.add_value(v) } - fn serialize_u64(self, v: u64) -> SerializeResult<()> { + fn serialize_u64(self, v: u64) -> Result<()> { self.add_value(v) } - fn serialize_i8(self, v: i8) -> SerializeResult<()> { + fn serialize_i8(self, v: i8) -> Result<()> { self.add_value(v) } - fn serialize_i16(self, v: i16) -> SerializeResult<()> { + fn serialize_i16(self, v: i16) -> Result<()> { self.add_value(v) } - fn serialize_i32(self, v: i32) -> SerializeResult<()> { + fn serialize_i32(self, v: i32) -> Result<()> { self.add_value(v) } - fn serialize_i64(self, v: i64) -> SerializeResult<()> { + fn serialize_i64(self, v: i64) -> Result<()> { self.add_value(v) } - fn serialize_f32(self, v: f32) -> SerializeResult<()> { + fn serialize_f32(self, v: f32) -> Result<()> { self.add_value(v) } - fn serialize_f64(self, v: f64) -> SerializeResult<()> { + fn serialize_f64(self, v: f64) -> Result<()> { self.add_value(v) } - fn serialize_str(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_char(self, c: char) -> SerializeResult<()> { + fn serialize_char(self, c: char) -> Result<()> { self.add_raw(encode_utf8(c).as_slice().len()) } - fn serialize_bytes(self, v: &[u8]) -> SerializeResult<()> { + fn serialize_bytes(self, v: &[u8]) -> Result<()> { try!(self.add_value(0 as u64)); self.add_raw(v.len()) } - fn serialize_none(self) -> SerializeResult<()> { + fn serialize_none(self) -> Result<()> { self.add_value(0 as u8) } - fn serialize_some(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(self, len: Option) -> SerializeResult { - let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); + fn serialize_seq(self, len: Option) -> Result { + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) } - fn serialize_seq_fixed_size(self, _len: usize) -> SerializeResult { + fn serialize_seq_fixed_size(self, _len: usize) -> Result { Ok(SizeCompound {ser: self}) } - fn serialize_tuple(self, _len: usize) -> SerializeResult { + fn serialize_tuple(self, _len: usize) -> Result { Ok(SizeCompound {ser: self}) } - fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { Ok(SizeCompound {ser: self}) } @@ -394,21 +333,21 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult + _len: usize) -> Result { try!(self.add_enum_tag(variant_index)); Ok(SizeCompound {ser: self}) } - fn serialize_map(self, len: Option) -> SerializeResult + fn serialize_map(self, len: Option) -> Result { - let len = try!(len.ok_or(SerializeError::SequenceMustHaveLength)); + let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); try!(self.serialize_u64(len as u64)); Ok(SizeCompound {ser: self}) } - fn serialize_struct(self, _name: &'static str, _len: usize) -> SerializeResult { + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Ok(SizeCompound {ser: self}) } @@ -416,20 +355,20 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { _name: &'static str, variant_index: usize, _variant: &'static str, - _len: usize) -> SerializeResult + _len: usize) -> Result { try!(self.add_enum_tag(variant_index)); Ok(SizeCompound {ser: self}) } - fn serialize_newtype_struct(self, _name: &'static str, v: &V) -> SerializeResult<()> { + 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: &'static str) -> SerializeResult<()> { + _variant: &'static str) -> Result<()> { self.add_enum_tag(variant_index) } @@ -437,7 +376,7 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { _name: &'static str, variant_index: usize, _variant: &'static str, - value: &V) -> SerializeResult<()> + value: &V) -> Result<()> { try!(self.add_enum_tag(variant_index)); value.serialize(self) @@ -453,17 +392,17 @@ impl<'a, W> serde::ser::SerializeSeq for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -472,17 +411,17 @@ impl<'a, W> serde::ser::SerializeTuple for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -491,17 +430,17 @@ impl<'a, W> serde::ser::SerializeTupleStruct for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -510,17 +449,17 @@ impl<'a, W> serde::ser::SerializeTupleVariant for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -529,24 +468,24 @@ impl<'a, W> serde::ser::SerializeMap for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_key(&mut self, value: &K) -> SerializeResult<()> + 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) -> SerializeResult<()> + fn serialize_value(&mut self, value: &V) -> Result<()> where V: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -555,17 +494,17 @@ impl<'a, W> serde::ser::SerializeStruct for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + 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) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -574,17 +513,17 @@ impl<'a, W> serde::ser::SerializeStructVariant for Compound<'a, W> where W: Write { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + 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) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -597,17 +536,17 @@ pub struct SizeCompound<'a> { impl<'a> serde::ser::SerializeSeq for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -615,17 +554,17 @@ impl<'a> serde::ser::SerializeSeq for SizeCompound<'a> impl<'a> serde::ser::SerializeTuple for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_element(&mut self, value: &T) -> SerializeResult<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -633,17 +572,17 @@ impl<'a> serde::ser::SerializeTuple for SizeCompound<'a> impl<'a> serde::ser::SerializeTupleStruct for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -651,17 +590,17 @@ impl<'a> serde::ser::SerializeTupleStruct for SizeCompound<'a> impl<'a> serde::ser::SerializeTupleVariant for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, value: &T) -> SerializeResult<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where T: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -669,24 +608,24 @@ impl<'a> serde::ser::SerializeTupleVariant for SizeCompound<'a> impl<'a> serde::ser::SerializeMap for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_key(&mut self, value: &K) -> SerializeResult<()> + 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) -> SerializeResult<()> + fn serialize_value(&mut self, value: &V) -> Result<()> where V: serde::ser::Serialize { value.serialize(&mut *self.ser) } #[inline] - fn end(self) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -694,17 +633,17 @@ impl<'a> serde::ser::SerializeMap for SizeCompound<'a> impl<'a> serde::ser::SerializeStruct for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + 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) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } @@ -712,17 +651,17 @@ impl<'a> serde::ser::SerializeStruct for SizeCompound<'a> impl<'a> serde::ser::SerializeStructVariant for SizeCompound<'a> { type Ok = (); - type Error = SerializeError; + type Error = Error; #[inline] - fn serialize_field(&mut self, _key: &'static str, value: &T) -> SerializeResult<()> + 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) -> SerializeResult<()> { + fn end(self) -> Result<()> { Ok(()) } } diff --git a/tests/test.rs b/tests/test.rs index dd13c9d..db9747b 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -11,7 +11,7 @@ use std::ops::Deref; use bincode::refbox::{RefBox, StrBox, SliceBox}; use bincode::SizeLimit::{self, Infinite, Bounded}; -use bincode::{serialize, serialized_size, deserialize, deserialize_from, DeserializeError, DeserializeResult}; +use bincode::{serialize, serialized_size, deserialize, deserialize_from, ErrorKind, Result}; fn proxy_encode(element: &V, size_limit: SizeLimit) -> Vec where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static @@ -211,12 +211,12 @@ fn test_fixed_size_array() { #[test] fn deserializing_errors() { - fn isize_invalid_deserialize(res: DeserializeResult) { - match res { - Err(DeserializeError::InvalidEncoding(_)) => {}, - Err(DeserializeError::Custom(ref s)) if s.contains("invalid encoding") => {}, - Err(DeserializeError::Custom(ref s)) if s.contains("invalid value") => {}, - _ => 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), } } @@ -235,11 +235,11 @@ fn deserializing_errors() { #[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(&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(&mut &serialized[..], Bounded(4)); assert!(deserialized.is_ok()); } @@ -256,7 +256,7 @@ fn char_serialization() { #[test] fn too_big_char_deserialize() { let serialized = vec![0x41]; - let deserialized: Result = deserialize_from(&mut &serialized[..], Bounded(1)); + let deserialized: Result = deserialize_from(&mut &serialized[..], Bounded(1)); assert!(deserialized.is_ok()); assert_eq!(deserialized.unwrap(), 'A'); } From cac9301615f0b515dd70221b871223470f085111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Fri, 10 Feb 2017 12:19:58 -0600 Subject: [PATCH 37/42] Remove InvalidEncoding struct (#111) --- src/serde/mod.rs | 32 ++++++++++---------------------- src/serde/reader.rs | 18 +++++++++--------- tests/test.rs | 2 +- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 48f99b4..3ac623a 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -39,7 +39,10 @@ pub enum ErrorKind { /// 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), + InvalidEncoding{ + desc: &'static str, + detail: Option + }, /// If (de)serializing a message takes more than the provided size limit, this /// error is returned. SizeLimit, @@ -51,7 +54,7 @@ impl error::Error for ErrorKind { fn description(&self) -> &str { match *self { ErrorKind::IoError(ref err) => error::Error::description(err), - ErrorKind::InvalidEncoding(ref ib) => ib.desc, + 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, @@ -62,7 +65,7 @@ impl error::Error for ErrorKind { fn cause(&self) -> Option<&error::Error> { match *self { ErrorKind::IoError(ref err) => err.cause(), - ErrorKind::InvalidEncoding(_) => None, + ErrorKind::InvalidEncoding{..} => None, ErrorKind::SequenceMustHaveLength => None, ErrorKind::SizeLimit => None, ErrorKind::Custom(_) => None, @@ -81,8 +84,10 @@ impl fmt::Display for ErrorKind { match *self { ErrorKind::IoError(ref ioerr) => write!(fmt, "IoError: {}", ioerr), - ErrorKind::InvalidEncoding(ref ib) => - write!(fmt, "InvalidEncoding: {}", ib), + 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 => @@ -105,23 +110,6 @@ impl serde::ser::Error for Error { } } -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct InvalidEncoding { - pub desc: &'static str, - pub 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) - } - } -} - /// Serializes an object directly into a `Writer`. /// /// If the serialization would take more bytes than allowed by `size_limit`, an error diff --git a/src/serde/reader.rs b/src/serde/reader.rs index e563202..cc7c0a5 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -5,7 +5,7 @@ use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; use serde_crate::de::Error as DeError; use ::SizeLimit; -use super::{Result, Error, ErrorKind, InvalidEncoding}; +use super::{Result, Error, ErrorKind}; /// A Deserializer that reads bytes from a buffer. /// @@ -59,10 +59,10 @@ impl Deserializer { try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer)); String::from_utf8(buffer).map_err(|err| - ErrorKind::InvalidEncoding(InvalidEncoding { + ErrorKind::InvalidEncoding{ desc: "error while decoding utf8 string", detail: Some(format!("Deserialize error: {}", err)) - }).into()) + }.into()) } } @@ -99,10 +99,10 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { 1 => visitor.visit_bool(true), 0 => visitor.visit_bool(false), value => { - Err(ErrorKind::InvalidEncoding(InvalidEncoding { + Err(ErrorKind::InvalidEncoding{ desc: "invalid u8 when decoding bool", detail: Some(format!("Expected 0 or 1, got {}", value)) - }).into()) + }.into()) } } } @@ -144,10 +144,10 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { { use std::str; - let error = ErrorKind::InvalidEncoding(InvalidEncoding { + let error = ErrorKind::InvalidEncoding{ desc: "Invalid char encoding", detail: None - }).into(); + }.into(); let mut buf = [0]; @@ -280,10 +280,10 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { match value { 0 => visitor.visit_none(), 1 => visitor.visit_some(&mut *self), - _ => Err(ErrorKind::InvalidEncoding(InvalidEncoding { + _ => Err(ErrorKind::InvalidEncoding{ desc: "invalid tag when decoding Option", detail: Some(format!("Expected 0 or 1, got {}", value)) - }).into()), + }.into()), } } diff --git a/tests/test.rs b/tests/test.rs index db9747b..2d109e3 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -213,7 +213,7 @@ fn test_fixed_size_array() { fn deserializing_errors() { fn isize_invalid_deserialize(res: Result) { match res.map_err(|e| *e) { - Err(ErrorKind::InvalidEncoding(_)) => {}, + 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), From 6ece2f5866cd07a9cfa629c361bf4866f215999f Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Thu, 23 Feb 2017 10:21:19 -0800 Subject: [PATCH 38/42] Add a "Bincode in the wild" section (#117) * Add a "Bincode in the wild" section * Change wording --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 From 3471118004e9d01ecf7739e64e42fe5f2c54fc3d Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 23 Feb 2017 12:31:59 -0800 Subject: [PATCH 39/42] Smarter deserialize_bytes and deserialize_byte_buf (#115) * Smarter deserialize_bytes * Make read_vec faster by pre-allocating the correct amount of space. Also, call visit_bytes in deserialize_bytes rather than visit_byte_buf. --- src/serde/reader.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/serde/reader.rs b/src/serde/reader.rs index cc7c0a5..29d2db7 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -51,14 +51,19 @@ impl Deserializer { self.read_bytes(size_of::() as u64) } - fn read_string(&mut self) -> Result { + fn read_vec(&mut self) -> Result> { let len = try!(serde::Deserialize::deserialize(&mut *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)); + 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) + } - String::from_utf8(buffer).map_err(|err| + 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)) @@ -192,13 +197,13 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_bytes(self, visitor: V) -> Result where V: serde::de::Visitor, { - self.deserialize_seq(visitor) + visitor.visit_bytes(&try!(self.read_vec())) } fn deserialize_byte_buf(self, visitor: V) -> Result where V: serde::de::Visitor, { - self.deserialize_seq(visitor) + visitor.visit_byte_buf(try!(self.read_vec())) } fn deserialize_enum(self, From 42a81647566edf8dd3dce3612cd2c20d52653d23 Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Fri, 24 Feb 2017 18:55:44 -0800 Subject: [PATCH 40/42] bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a5f344f..7091717 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "1.0.0-alpha1" +version = "1.0.0-alpha3" authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Daniel Griffen"] repository = "https://github.com/TyOverby/bincode" From 1631cb2d8089de6c17291714a3a7914a5cdfffcd Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Fri, 24 Feb 2017 18:58:46 -0800 Subject: [PATCH 41/42] Make Reader and Writer generic on Endianness (#103) * Make Reader and Writer generic on Endianness * make alternate API modules * add test asserting that big endian encoding is different from little endian encoding * clean up tests --- src/lib.rs | 58 ++++++++++++++++- src/serde/mod.rs | 20 +++--- src/serde/reader.rs | 40 ++++++------ src/serde/writer.rs | 75 +++++++++++----------- tests/test.rs | 148 +++++++++++++++++++++++--------------------- 5 files changed, 205 insertions(+), 136 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c76e219..2982637 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,63 @@ extern crate serde as serde_crate; pub mod refbox; mod serde; -pub use serde::*; +pub mod endian_choice { + pub use super::serde::{serialize, serialize_into, deserialize, deserialize_from}; +} + +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. /// diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 3ac623a..9caeb0a 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -6,6 +6,7 @@ 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, @@ -118,9 +119,8 @@ impl serde::ser::Error for Error { /// 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) -> Result<()> - 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 => { } @@ -130,7 +130,7 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limi } } - let mut serializer = Serializer::new(writer); + let mut serializer = Serializer::<_, E>::new(writer); serde::Serialize::serialize(value, &mut serializer) } @@ -138,7 +138,7 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limi /// /// If the serialization would take more bytes than allowed by `size_limit`, /// an error is returned. -pub fn serialize(value: &T, size_limit: SizeLimit) -> Result> +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 @@ -152,7 +152,7 @@ pub fn serialize(value: &T, size_limit: SizeLimit) -> Result> SizeLimit::Infinite => Vec::new() }; - try!(serialize_into(&mut writer, value, SizeLimit::Infinite)); + try!(serialize_into::<_, _, E>(&mut writer, value, SizeLimit::Infinite)); Ok(writer) } @@ -190,11 +190,11 @@ pub fn serialized_size_bounded(value: &T, max: u64) -> Option /// 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) -> Result +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) } @@ -202,9 +202,9 @@ pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> /// /// 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]) -> Result +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 29d2db7..8d6e2db 100644 --- a/src/serde/reader.rs +++ b/src/serde/reader.rs @@ -1,6 +1,7 @@ use std::io::Read; +use std::marker::PhantomData; -use byteorder::{BigEndian, ReadBytesExt}; +use byteorder::{ReadBytesExt, ByteOrder}; use serde_crate as serde; use serde_crate::de::value::ValueDeserializer; use serde_crate::de::Error as DeError; @@ -17,18 +18,20 @@ use super::{Result, Error, ErrorKind}; /// serde::Deserialize::deserialize(&mut deserializer); /// let bytes_read = d.bytes_read(); /// ``` -pub struct Deserializer { +pub struct Deserializer { reader: R, size_limit: SizeLimit, - read: u64 + read: u64, + _phantom: PhantomData, } -impl Deserializer { - pub fn new(r: R, size_limit: SizeLimit) -> Deserializer { +impl Deserializer { + pub fn new(r: R, size_limit: SizeLimit) -> Deserializer { Deserializer { reader: r, size_limit: size_limit, - read: 0 + read: 0, + _phantom: PhantomData } } @@ -78,14 +81,13 @@ macro_rules! impl_nums { 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 &'a mut Deserializer { +impl<'a, R: Read, E: ByteOrder> serde::Deserializer for &'a mut Deserializer { type Error = Error; #[inline] @@ -212,7 +214,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { visitor: V) -> Result where V: serde::de::Visitor, { - impl<'a, R: Read + 'a> serde::de::EnumVisitor for &'a mut Deserializer { + impl<'a, R: Read + 'a, E: ByteOrder> serde::de::EnumVisitor for &'a mut Deserializer { type Error = Error; type Variant = Self; @@ -233,9 +235,9 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { visitor: V) -> Result where V: serde::de::Visitor, { - struct TupleVisitor<'a, R: Read + 'a>(&'a mut Deserializer); + struct TupleVisitor<'a, R: Read + 'a, E: ByteOrder + 'a>(&'a mut Deserializer); - impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, R> { + 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> @@ -254,12 +256,12 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { visitor: V) -> Result where V: serde::de::Visitor, { - struct SeqVisitor<'a, R: Read + 'a> { - deserializer: &'a mut Deserializer, + 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, R> { + impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::SeqVisitor for SeqVisitor<'a, R, E> { type Error = Error; fn visit_seed(&mut self, seed: T) -> Result> @@ -303,12 +305,12 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { fn deserialize_map(self, visitor: V) -> Result where V: serde::de::Visitor, { - struct MapVisitor<'a, R: Read + 'a> { - deserializer: &'a mut Deserializer, + 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, R> { + impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::MapVisitor for MapVisitor<'a, R, E> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result> @@ -387,7 +389,7 @@ impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer { } } -impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer { +impl<'a, R: Read, E: ByteOrder> serde::de::VariantVisitor for &'a mut Deserializer { type Error = Error; fn visit_unit(self) -> Result<()> { diff --git a/src/serde/writer.rs b/src/serde/writer.rs index b44a6bf..3bb10fc 100644 --- a/src/serde/writer.rs +++ b/src/serde/writer.rs @@ -1,9 +1,10 @@ use std::io::Write; use std::u32; +use std::marker::PhantomData; use serde_crate as serde; -use byteorder::{BigEndian, WriteBytesExt}; +use byteorder::{WriteBytesExt, ByteOrder}; use super::{Result, Error, ErrorKind}; @@ -11,14 +12,16 @@ use super::{Result, Error, ErrorKind}; /// /// This struct should not be used often. /// For most cases, prefer the `encode_into` function. -pub struct Serializer { +pub struct Serializer { writer: W, + _phantom: PhantomData, } -impl Serializer { - pub fn new(w: W) -> Serializer { +impl Serializer { + pub fn new(w: W) -> Serializer { Serializer { writer: w, + _phantom: PhantomData, } } @@ -31,16 +34,16 @@ impl Serializer { } } -impl<'a, W: Write> serde::Serializer for &'a mut Serializer { +impl<'a, W: Write, E: ByteOrder> serde::Serializer for &'a mut Serializer { type Ok = (); type Error = Error; - type SerializeSeq = Compound<'a, W>; - type SerializeTuple = Compound<'a, W>; - type SerializeTupleStruct = Compound<'a, W>; - type SerializeTupleVariant = Compound<'a, W>; - type SerializeMap = Compound<'a, W>; - type SerializeStruct = Compound<'a, W>; - type SerializeStructVariant = Compound<'a, W>; + 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(self) -> Result<()> { Ok(()) } @@ -55,15 +58,15 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_u16(self, v: u16) -> Result<()> { - self.writer.write_u16::(v).map_err(Into::into) + self.writer.write_u16::(v).map_err(Into::into) } fn serialize_u32(self, v: u32) -> Result<()> { - self.writer.write_u32::(v).map_err(Into::into) + self.writer.write_u32::(v).map_err(Into::into) } fn serialize_u64(self, v: u64) -> Result<()> { - self.writer.write_u64::(v).map_err(Into::into) + self.writer.write_u64::(v).map_err(Into::into) } fn serialize_i8(self, v: i8) -> Result<()> { @@ -71,23 +74,23 @@ impl<'a, W: Write> serde::Serializer for &'a mut Serializer { } fn serialize_i16(self, v: i16) -> Result<()> { - self.writer.write_i16::(v).map_err(Into::into) + self.writer.write_i16::(v).map_err(Into::into) } fn serialize_i32(self, v: i32) -> Result<()> { - self.writer.write_i32::(v).map_err(Into::into) + self.writer.write_i32::(v).map_err(Into::into) } fn serialize_i64(self, v: i64) -> Result<()> { - self.writer.write_i64::(v).map_err(Into::into) + self.writer.write_i64::(v).map_err(Into::into) } fn serialize_f32(self, v: f32) -> Result<()> { - self.writer.write_f32::(v).map_err(Into::into) + self.writer.write_f32::(v).map_err(Into::into) } fn serialize_f64(self, v: f64) -> Result<()> { - self.writer.write_f64::(v).map_err(Into::into) + self.writer.write_f64::(v).map_err(Into::into) } fn serialize_str(self, v: &str) -> Result<()> { @@ -384,12 +387,12 @@ impl<'a> serde::Serializer for &'a mut SizeChecker { } #[doc(hidden)] -pub struct Compound<'a, W: 'a> { - ser: &'a mut Serializer, +pub struct Compound<'a, W: 'a, E: ByteOrder + 'a> { + ser: &'a mut Serializer, } -impl<'a, W> serde::ser::SerializeSeq for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeSeq for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -407,8 +410,8 @@ impl<'a, W> serde::ser::SerializeSeq for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeTuple for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeTuple for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -426,8 +429,8 @@ impl<'a, W> serde::ser::SerializeTuple for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeTupleStruct for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeTupleStruct for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -445,8 +448,8 @@ impl<'a, W> serde::ser::SerializeTupleStruct for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeTupleVariant for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeTupleVariant for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -464,8 +467,8 @@ impl<'a, W> serde::ser::SerializeTupleVariant for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeMap for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeMap for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -490,8 +493,8 @@ impl<'a, W> serde::ser::SerializeMap for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeStruct for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeStruct for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; @@ -509,8 +512,8 @@ impl<'a, W> serde::ser::SerializeStruct for Compound<'a, W> } } -impl<'a, W> serde::ser::SerializeStructVariant for Compound<'a, W> - where W: Write +impl<'a, W, E> serde::ser::SerializeStructVariant for Compound<'a, W, E> + where W: Write, E: ByteOrder { type Ok = (); type Error = Error; diff --git a/tests/test.rs b/tests/test.rs index 2d109e3..2c8fe8b 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -3,6 +3,7 @@ extern crate serde_derive; extern crate bincode; extern crate serde; +extern crate byteorder; use std::fmt::Debug; use std::collections::HashMap; @@ -10,29 +11,13 @@ use std::ops::Deref; use bincode::refbox::{RefBox, StrBox, SliceBox}; -use bincode::SizeLimit::{self, Infinite, Bounded}; -use bincode::{serialize, serialized_size, deserialize, deserialize_from, ErrorKind, Result}; +use bincode::SizeLimit::{Infinite, Bounded}; +use bincode::{serialized_size, ErrorKind, Result}; +use bincode::endian_choice::{serialize, deserialize}; -fn proxy_encode(element: &V, size_limit: SizeLimit) -> Vec - where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static -{ - let v2 = serialize(element, size_limit).unwrap(); - v2 -} - -fn proxy_decode(slice: &[u8]) -> V - where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static -{ - let e2 = deserialize(slice).unwrap(); - e2 -} - -fn proxy_encoded_size(element: &V) -> u64 - where V: serde::Serialize + PartialEq + Debug + 'static -{ - let serde_size = serialized_size(element); - serde_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: serde::Serialize+serde::Deserialize+PartialEq+Debug+'static @@ -42,20 +27,35 @@ fn the_same(element: V) where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static { let rf = RefBox::new(v); - let encoded = serialize(&rf, Infinite).unwrap(); - let decoded: RefBox<'static, V> = deserialize(&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] @@ -220,26 +220,26 @@ fn deserializing_errors() { } } - 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![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..])); // Out-of-bounds variant #[derive(Serialize, Deserialize, Debug)] enum Test { One, Two, }; - isize_invalid_deserialize(deserialize::(&vec![0, 0, 0, 5][..])); - isize_invalid_deserialize(deserialize::>(&vec![5, 0][..])); + 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()); } @@ -247,8 +247,8 @@ fn too_big_deserialize() { fn char_serialization() { let chars = "Aa\0☺♪"; for c in chars.chars() { - let encoded = serialize(&c, Bounded(4)).expect("serializing char failed"); - let decoded: char = deserialize(&encoded).expect("deserializing failed"); + let encoded = serialize_little(&c, Bounded(4)).expect("serializing char failed"); + let decoded: char = deserialize_little(&encoded).expect("deserializing failed"); assert_eq!(decoded, c); } } @@ -256,47 +256,47 @@ fn char_serialization() { #[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_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] @@ -319,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), @@ -330,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), @@ -343,8 +343,8 @@ fn test_refbox_serialize() { #[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[..]); } @@ -352,8 +352,8 @@ fn test_strbox_serialize() { #[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); @@ -364,7 +364,7 @@ fn test_slicebox_serialize() { #[test] fn test_multi_strings_serialize() { - assert!(serialize(&("foo", "bar", "baz"), Infinite).is_ok()); + assert!(serialize_little(&("foo", "bar", "baz"), Infinite).is_ok()); } /* @@ -384,8 +384,8 @@ fn test_oom_protection() { fn path_buf() { use std::path::{Path, PathBuf}; let path = Path::new("foo").to_path_buf(); - let serde_encoded = serialize(&path, Infinite).unwrap(); - let decoded: PathBuf = 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()); } @@ -394,8 +394,16 @@ fn bytes() { use serde::bytes::Bytes; let data = b"abc\0123"; - let s = serialize(&data, Infinite).unwrap(); - let s2 = serialize(&Bytes::new(data), Infinite).unwrap(); + 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); +} From 1567d65ae99a87bd1d9cd1e52dd3612acfd5603b Mon Sep 17 00:00:00 2001 From: Ty Overby Date: Fri, 24 Feb 2017 19:04:46 -0800 Subject: [PATCH 42/42] fix oom --- Cargo.toml | 2 +- tests/test.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7091717..2cb8a1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "1.0.0-alpha3" +version = "1.0.0-alpha4" authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Daniel Griffen"] repository = "https://github.com/TyOverby/bincode" diff --git a/tests/test.rs b/tests/test.rs index 2c8fe8b..914013c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -221,7 +221,7 @@ fn deserializing_errors() { } isize_invalid_deserialize(deserialize_little::(&vec![0xA][..])); - isize_invalid_deserialize(deserialize_little::(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..])); + isize_invalid_deserialize(deserialize_little::(&vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF][..])); // Out-of-bounds variant #[derive(Serialize, Deserialize, Debug)] enum Test {