diff --git a/.travis.yml b/.travis.yml
index 42fe126..35b04d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,19 +3,3 @@ rust:
- stable
- beta
- nightly
-
-after_success: |
- [ $TRAVIS_BRANCH = master ] &&
- [ $TRAVIS_PULL_REQUEST = false ] &&
- cargo doc &&
- echo "" > target/doc/index.html &&
- sudo pip install ghp-import &&
- ghp-import -n target/doc &&
- git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
-env:
- global:
- - secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI=
-matrix:
- allow_failures:
- - rust: stable
- - rust: beta
diff --git a/Cargo.toml b/Cargo.toml
index 83d96f2..2cb8a1f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,20 +1,21 @@
[package]
name = "bincode"
-version = "0.5.1"
-authors = ["Ty Overby ", "Francesco Mazzoli "]
+version = "1.0.0-alpha4"
+authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Daniel Griffen"]
repository = "https://github.com/TyOverby/bincode"
-documentation = "http://tyoverby.github.io/bincode/bincode/"
+documentation = "https://docs.rs/bincode"
keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
license = "MIT"
-description = "A binary serialization / deserialization strategy and implementation."
+description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!"
[dependencies]
-rustc-serialize = "0.3.*"
-byteorder = "0.4.*"
-num = "0.1.*"
-serde = "0.7.*"
+byteorder = "1.0.0"
+num-traits = "0.1.32"
+
+[dependencies.serde]
+version = "0.9.*"
[dev-dependencies]
-serde_macros = "0.7.*"
+serde_derive = "0.9.*"
diff --git a/README.md b/README.md
index ffc1658..f13ec72 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,13 @@ perfectly with other stream-based apis such as rust files, network streams,
and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression
library.
-[Api Documentation](http://tyoverby.github.io/bincode/bincode/)
+## [Api Documentation](http://tyoverby.github.io/bincode/bincode/)
+
+## Bincode in the wild
+
+* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages.
+* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging.
+* [servo/icp-channel](https://github.com/servo/ipc-channel): Ipc-Channel uses Bincode to send structs between processes using a channel-like API.
## Example
```rust
diff --git a/changelist.org b/changelist.org
new file mode 100644
index 0000000..761068b
--- /dev/null
+++ b/changelist.org
@@ -0,0 +1,18 @@
+* 1.0.0
+** Removed depricated rustc-serialize support
+ Rustc-serialize was a stopgap until projects like Serde were able to catch up.
+ With macros stabilization on its way, we are able to switch to serde without any
+ big user-friendliness issues. Major congratulations to Serde for coming this far!
+
+** Moved Refbox, Strbox and Slicebox into a "refbox" module
+ Refbox, Strbox and Slicebox are still an integral piece of bincode, but since
+ they are mainly used by power-users, this move will make the crate API more organized
+ and easier for new users to understand.
+
+** Upgraded to Serde 0.9.*
+ Serde 0.9.* gives us a better API surface area and allows use of procedural macros for
+ deriving serialize and deserialize implemenetations.
+
+** Moved serde functions into global module
+ Since serde is the only supported serialization mechanism, it makes sense to have these
+ functions available at the top level.
diff --git a/examples/basic.rs b/examples/basic.rs
index 670f6bc..c5d9d3e 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -1,5 +1,6 @@
+/*
extern crate bincode;
-extern crate rustc_serialize;
+extern crate
use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
@@ -29,3 +30,6 @@ fn main() {
assert!(world == decoded);
}
+ */
+
+fn main() {}
diff --git a/src/lib.rs b/src/lib.rs
index 1baf135..2982637 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -16,17 +16,16 @@
//! ### Using Basic Functions
//!
//! ```rust
-//! #![allow(unstable)]
//! extern crate bincode;
-//! use bincode::rustc_serialize::{encode, decode};
+//! use bincode::{serialize, deserialize};
//! fn main() {
//! // The object that we will serialize.
//! let target = Some("hello world".to_string());
//! // The maximum size of the encoded message.
//! let limit = bincode::SizeLimit::Bounded(20);
//!
-//! let encoded: Vec = encode(&target, limit).unwrap();
-//! let decoded: Option = decode(&encoded[..]).unwrap();
+//! let encoded: Vec = serialize(&target, limit).unwrap();
+//! let decoded: Option = deserialize(&encoded[..]).unwrap();
//! assert_eq!(target, decoded);
//! }
//! ```
@@ -37,17 +36,70 @@
#![doc(html_logo_url = "./icon.png")]
-extern crate rustc_serialize as rustc_serialize_crate;
extern crate byteorder;
-extern crate num;
+extern crate num_traits;
extern crate serde as serde_crate;
+pub mod refbox;
+mod serde;
-pub use refbox::{RefBox, StrBox, SliceBox};
+pub mod endian_choice {
+ pub use super::serde::{serialize, serialize_into, deserialize, deserialize_from};
+}
-mod refbox;
-pub mod rustc_serialize;
-pub mod serde;
+use std::io::{Read, Write};
+
+pub use serde::{Deserializer, Serializer, ErrorKind, Error, Result, serialized_size, serialized_size_bounded};
+
+/// Deserializes a slice of bytes into an object.
+///
+/// This method does not have a size-limit because if you already have the bytes
+/// in memory, then you don't gain anything by having a limiter.
+pub fn deserialize(bytes: &[u8]) -> serde::Result
+ where T: serde_crate::Deserialize,
+{
+ serde::deserialize::<_, byteorder::LittleEndian>(bytes)
+}
+
+/// Deserializes an object directly from a `Buffer`ed Reader.
+///
+/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
+/// A SizeLimit can help prevent an attacker from flooding your server with
+/// a neverending stream of values that runs your server out of memory.
+///
+/// If this returns an `Error`, assume that the buffer that you passed
+/// in is in an invalid state, as the error could be returned during any point
+/// in the reading.
+pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> serde::Result
+ where R: Read,
+ T: serde_crate::Deserialize,
+{
+ serde::deserialize_from::<_, _, byteorder::LittleEndian>(reader, size_limit)
+}
+
+/// Serializes an object directly into a `Writer`.
+///
+/// If the serialization would take more bytes than allowed by `size_limit`, an error
+/// is returned and *no bytes* will be written into the `Writer`.
+///
+/// If this returns an `Error` (other than SizeLimit), assume that the
+/// writer is in an invalid state, as writing could bail out in the middle of
+/// serializing.
+pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> serde::Result<()>
+ where W: Write, T: serde_crate::Serialize
+{
+ serde::serialize_into::<_, _, byteorder::LittleEndian>(writer, value, size_limit)
+}
+
+/// Serializes a serializable object into a `Vec` of bytes.
+///
+/// If the serialization would take more bytes than allowed by `size_limit`,
+/// an error is returned.
+pub fn serialize(value: &T, size_limit: SizeLimit) -> serde::Result>
+ where T: serde_crate::Serialize
+{
+ serde::serialize::<_, byteorder::LittleEndian>(value, size_limit)
+}
/// A limit on the amount of bytes that can be read or written.
///
@@ -66,10 +118,9 @@ pub mod serde;
/// that is larger than your decoder expects. By supplying a size limit to an
/// encoding function, the encoder will verify that the structure can be encoded
/// within that limit. This verification occurs before any bytes are written to
-/// the Writer, so recovering from an the error is easy.
+/// the Writer, so recovering from an error is easy.
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum SizeLimit {
Infinite,
Bounded(u64)
}
-
diff --git a/src/refbox.rs b/src/refbox.rs
index b115357..be663f9 100644
--- a/src/refbox.rs
+++ b/src/refbox.rs
@@ -1,8 +1,6 @@
use std::boxed::Box;
use std::ops::Deref;
-use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder};
-
use serde_crate as serde;
/// A struct for encoding nested reference types.
@@ -139,32 +137,18 @@ impl RefBox<'static, T> {
}
}
-
-impl <'a, T: Encodable> Encodable for RefBox<'a, T> {
- fn encode(&self, s: &mut S) -> Result<(), S::Error> {
- self.inner.encode(s)
- }
-}
-
-impl Decodable for RefBox<'static, T> {
- fn decode(d: &mut D) -> Result, D::Error> {
- let inner = try!(Decodable::decode(d));
- Ok(RefBox{inner: inner})
- }
-}
-
impl<'a, T> serde::Serialize for RefBox<'a, T>
where T: serde::Serialize,
{
- fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
+ fn serialize(&self, serializer: S) -> Result
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
-impl serde::Deserialize for RefBox<'static, T> {
- fn deserialize(deserializer: &mut D) -> Result
+impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> {
+ fn deserialize(deserializer: D) -> Result
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
@@ -234,21 +218,9 @@ impl StrBox<'static> {
}
}
-impl <'a> Encodable for StrBox<'a> {
- fn encode(&self, s: &mut S) -> Result<(), S::Error> {
- self.inner.encode(s)
- }
-}
-
-impl Decodable for StrBox<'static> {
- fn decode(d: &mut D) -> Result, D::Error> {
- let inner: RefBoxInner<'static, str, String> = try!(Decodable::decode(d));
- Ok(StrBox{inner: inner})
- }
-}
impl<'a> serde::Serialize for StrBox<'a> {
- fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
+ fn serialize(&self, serializer: S) -> Result
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
@@ -256,7 +228,7 @@ impl<'a> serde::Serialize for StrBox<'a> {
}
impl serde::Deserialize for StrBox<'static> {
- fn deserialize(deserializer: &mut D) -> Result
+ fn deserialize(deserializer: D) -> Result
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
@@ -321,31 +293,19 @@ impl SliceBox<'static, T> {
}
}
-impl <'a, T: Encodable> Encodable for SliceBox<'a, T> {
- fn encode(&self, s: &mut S) -> Result<(), S::Error> {
- self.inner.encode(s)
- }
-}
-
-impl Decodable for SliceBox<'static, T> {
- fn decode(d: &mut D) -> Result, D::Error> {
- let inner: RefBoxInner<'static, [T], Vec> = try!(Decodable::decode(d));
- Ok(SliceBox{inner: inner})
- }
-}
impl<'a, T> serde::Serialize for SliceBox<'a, T>
where T: serde::Serialize,
{
- fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
+ fn serialize(&self, serializer: S) -> Result
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
-impl serde::Deserialize for SliceBox<'static, T> {
- fn deserialize(deserializer: &mut D) -> Result
+impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> {
+ fn deserialize(deserializer: D) -> Result
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
@@ -353,20 +313,12 @@ impl serde::Deserialize for SliceBox<'static, T> {
}
}
-impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> {
- fn encode(&self, s: &mut S) -> Result<(), S::Error> {
- match self {
- &RefBoxInner::Ref(ref r) => r.encode(s),
- &RefBoxInner::Box(ref b) => b.encode(s)
- }
- }
-}
impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B>
where A: serde::Serialize,
B: serde::Serialize,
{
- fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
+ fn serialize(&self, serializer: S) -> Result
where S: serde::Serializer
{
match self {
@@ -377,17 +329,10 @@ impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B>
}
-impl Decodable for RefBoxInner<'static, A, B> {
- fn decode(d: &mut D) -> Result, D::Error> {
- let decoded = try!(Decodable::decode(d));
- Ok(RefBoxInner::Box(decoded))
- }
-}
-
-impl serde::Deserialize for RefBoxInner<'static, A, B>
+impl<'a, A: ?Sized, B> serde::Deserialize for RefBoxInner<'a, A, B>
where B: serde::Deserialize,
{
- fn deserialize(deserializer: &mut D) -> Result
+ fn deserialize(deserializer: D) -> Result
where D: serde::Deserializer
{
let deserialized = try!(serde::Deserialize::deserialize(deserializer));
diff --git a/src/rustc_serialize/mod.rs b/src/rustc_serialize/mod.rs
deleted file mode 100644
index b7565ed..0000000
--- a/src/rustc_serialize/mod.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-//! A collection of serialization and deserialization functions
-//! that use the `rustc_serialize` crate for the encodable and decodable
-//! implementation.
-
-use rustc_serialize_crate::{Encodable, Decodable};
-use std::io::{Write, Read};
-use ::SizeLimit;
-
-pub use self::writer::{SizeChecker, EncoderWriter, EncodingResult, EncodingError};
-pub use self::reader::{DecoderReader, DecodingResult, DecodingError};
-
-mod reader;
-mod writer;
-
-/// Encodes an encodable object into a `Vec` of bytes.
-///
-/// If the encoding would take more bytes than allowed by `size_limit`,
-/// an error is returned.
-pub fn encode(t: &T, size_limit: SizeLimit) -> EncodingResult> {
- // Since we are putting values directly into a vector, we can do size
- // computation out here and pre-allocate a buffer of *exactly*
- // the right size.
- let mut w = if let SizeLimit::Bounded(l) = size_limit {
- let actual_size = encoded_size_bounded(t, l);
- let actual_size = try!(actual_size.ok_or(EncodingError::SizeLimit));
- Vec::with_capacity(actual_size as usize)
- } else {
- vec![]
- };
-
- match encode_into(t, &mut w, SizeLimit::Infinite) {
- Ok(()) => Ok(w),
- Err(e) => Err(e)
- }
-}
-
-/// Decodes a slice of bytes into an object.
-///
-/// This method does not have a size-limit because if you already have the bytes
-/// in memory, then you don't gain anything by having a limiter.
-pub fn decode(b: &[u8]) -> DecodingResult {
- let mut b = b;
- decode_from(&mut b, SizeLimit::Infinite)
-}
-
-/// Encodes an object directly into a `Writer`.
-///
-/// If the encoding would take more bytes than allowed by `size_limit`, an error
-/// is returned and *no bytes* will be written into the `Writer`.
-///
-/// If this returns an `EncodingError` (other than SizeLimit), assume that the
-/// writer is in an invalid state, as writing could bail out in the middle of
-/// encoding.
-pub fn encode_into(t: &T,
- w: &mut W,
- size_limit: SizeLimit)
- -> EncodingResult<()> {
- try!(match size_limit {
- SizeLimit::Infinite => Ok(()),
- SizeLimit::Bounded(x) => {
- let mut size_checker = SizeChecker::new(x);
- t.encode(&mut size_checker)
- }
- });
-
- t.encode(&mut writer::EncoderWriter::new(w))
-}
-
-/// Decoes an object directly from a `Buffer`ed Reader.
-///
-/// If the provided `SizeLimit` is reached, the decode will bail immediately.
-/// A SizeLimit can help prevent an attacker from flooding your server with
-/// a neverending stream of values that runs your server out of memory.
-///
-/// If this returns an `DecodingError`, assume that the buffer that you passed
-/// in is in an invalid state, as the error could be returned during any point
-/// in the reading.
-pub fn decode_from(r: &mut R, size_limit: SizeLimit) -> DecodingResult {
- Decodable::decode(&mut reader::DecoderReader::new(r, size_limit))
-}
-
-
-/// Returns the size that an object would be if encoded using bincode.
-///
-/// This is used internally as part of the check for encode_into, but it can
-/// be useful for preallocating buffers if thats your style.
-pub fn encoded_size(t: &T) -> u64 {
- use std::u64::MAX;
- let mut size_checker = SizeChecker::new(MAX);
- t.encode(&mut size_checker).ok();
- size_checker.written
-}
-
-/// Given a maximum size limit, check how large an object would be if it
-/// were to be encoded.
-///
-/// If it can be encoded in `max` or fewer bytes, that number will be returned
-/// inside `Some`. If it goes over bounds, then None is returned.
-pub fn encoded_size_bounded(t: &T, max: u64) -> Option {
- let mut size_checker = SizeChecker::new(max);
- t.encode(&mut size_checker).ok().map(|_| size_checker.written)
-}
-
diff --git a/src/rustc_serialize/reader.rs b/src/rustc_serialize/reader.rs
deleted file mode 100644
index d3dbfb3..0000000
--- a/src/rustc_serialize/reader.rs
+++ /dev/null
@@ -1,397 +0,0 @@
-use std::io::Read;
-use std::io::Error as IoError;
-use std::error::Error;
-use std::fmt;
-use std::convert::From;
-
-use rustc_serialize_crate::Decoder;
-
-use byteorder::{BigEndian, ReadBytesExt};
-use byteorder::Error as ByteOrderError;
-use ::SizeLimit;
-
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub struct InvalidEncoding {
- desc: &'static str,
- detail: Option,
-}
-
-impl fmt::Display for InvalidEncoding {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- InvalidEncoding { detail: None, desc } =>
- write!(fmt, "{}", desc),
- InvalidEncoding { detail: Some(ref detail), desc } =>
- write!(fmt, "{} ({})", desc, detail)
- }
- }
-}
-
-/// An error that can be produced during decoding.
-///
-/// If decoding from a Buffer, assume that the buffer has been left
-/// in an invalid state.
-#[derive(Debug)]
-pub enum DecodingError {
- /// If the error stems from the reader that is being used
- /// during decoding, that error will be stored and returned here.
- IoError(IoError),
- /// If the bytes in the reader are not decodable because of an invalid
- /// encoding, this error will be returned. This error is only possible
- /// if a stream is corrupted. A stream produced from `encode` or `encode_into`
- /// should **never** produce an InvalidEncoding error.
- InvalidEncoding(InvalidEncoding),
- /// If decoding a message takes more than the provided size limit, this
- /// error is returned.
- SizeLimit
-}
-
-impl fmt::Display for DecodingError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- DecodingError::IoError(ref ioerr) =>
- write!(fmt, "IoError: {}", ioerr),
- DecodingError::InvalidEncoding(ref ib) =>
- write!(fmt, "InvalidEncoding: {}", ib),
- DecodingError::SizeLimit =>
- write!(fmt, "SizeLimit")
- }
- }
-}
-
-pub type DecodingResult = Result;
-
-fn wrap_io(err: ByteOrderError) -> DecodingError {
- match err {
- ByteOrderError::Io(ioe) => DecodingError::IoError(ioe),
- ByteOrderError::UnexpectedEOF =>
- DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "Unexpected EOF while reading a multi-byte number",
- detail: None
- })
- }
-}
-
-impl Error for DecodingError {
- fn description(&self) -> &str {
- match *self {
- DecodingError::IoError(ref err) => Error::description(err),
- DecodingError::InvalidEncoding(ref ib) => ib.desc,
- DecodingError::SizeLimit => "the size limit for decoding has been reached"
- }
- }
-
- fn cause(&self) -> Option<&Error> {
- match *self {
- DecodingError::IoError(ref err) => err.cause(),
- DecodingError::InvalidEncoding(_) => None,
- DecodingError::SizeLimit => None
- }
- }
-}
-
-impl From for DecodingError {
- fn from(err: IoError) -> DecodingError {
- DecodingError::IoError(err)
- }
-}
-
-/// A Decoder that reads bytes from a buffer.
-///
-/// This struct should rarely be used.
-/// In most cases, prefer the `decode_from` function.
-///
-/// ```rust,ignore
-/// let dr = bincode::rustc_serialize::DecoderReader::new(&mut some_reader, SizeLimit::Infinite);
-/// let result: T = Decodable::decode(&mut dr);
-/// let bytes_read = dr.bytes_read();
-/// ```
-pub struct DecoderReader<'a, R: 'a> {
- reader: &'a mut R,
- size_limit: SizeLimit,
- read: u64
-}
-
-impl<'a, R: Read> DecoderReader<'a, R> {
- pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> {
- DecoderReader {
- reader: r,
- size_limit: size_limit,
- read: 0
- }
- }
-
- /// Returns the number of bytes read from the contained Reader.
- pub fn bytes_read(&self) -> u64 {
- self.read
- }
-}
-
-impl <'a, A> DecoderReader<'a, A> {
- fn read_bytes(&mut self, count: u64) -> Result<(), DecodingError> {
- self.read += count;
- match self.size_limit {
- SizeLimit::Infinite => Ok(()),
- SizeLimit::Bounded(x) if self.read <= x => Ok(()),
- SizeLimit::Bounded(_) => Err(DecodingError::SizeLimit)
- }
- }
-
- fn read_type(&mut self) -> Result<(), DecodingError> {
- use std::mem::size_of;
- self.read_bytes(size_of::() as u64)
- }
-}
-
-impl<'a, R: Read> Decoder for DecoderReader<'a, R> {
- type Error = DecodingError;
-
- fn read_nil(&mut self) -> DecodingResult<()> {
- Ok(())
- }
- fn read_usize(&mut self) -> DecodingResult {
- Ok(try!(self.read_u64().map(|x| x as usize)))
- }
- fn read_u64(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_u64::().map_err(wrap_io)
- }
- fn read_u32(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_u32::().map_err(wrap_io)
- }
- fn read_u16(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_u16::().map_err(wrap_io)
- }
- fn read_u8(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_u8().map_err(wrap_io)
- }
- fn read_isize(&mut self) -> DecodingResult {
- self.read_i64().map(|x| x as isize)
- }
- fn read_i64(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_i64::().map_err(wrap_io)
- }
- fn read_i32(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_i32::().map_err(wrap_io)
- }
- fn read_i16(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_i16::().map_err(wrap_io)
- }
- fn read_i8(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_i8().map_err(wrap_io)
- }
- fn read_bool(&mut self) -> DecodingResult {
- let x = try!(self.read_i8());
- match x {
- 1 => Ok(true),
- 0 => Ok(false),
- _ => Err(DecodingError::InvalidEncoding(InvalidEncoding{
- desc: "invalid u8 when decoding bool",
- detail: Some(format!("Expected 0 or 1, got {}", x))
- })),
- }
- }
- fn read_f64(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_f64::().map_err(wrap_io)
- }
- fn read_f32(&mut self) -> DecodingResult {
- try!(self.read_type::());
- self.reader.read_f32::().map_err(wrap_io)
- }
- fn read_char(&mut self) -> DecodingResult {
- use std::str;
-
- let error = DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "Invalid char encoding",
- detail: None
- });
-
- let mut buf = [0];
-
- let _ = try!(self.reader.read(&mut buf[..]));
- let first_byte = buf[0];
- let width = utf8_char_width(first_byte);
- if width == 1 { return Ok(first_byte as char) }
- if width == 0 { return Err(error)}
-
- let mut buf = [first_byte, 0, 0, 0];
- {
- let mut start = 1;
- while start < width {
- match try!(self.reader.read(&mut buf[start .. width])) {
- n if n == width - start => break,
- n if n < width - start => { start += n; }
- _ => return Err(error)
- }
- }
- }
-
- let res = try!(match str::from_utf8(&buf[..width]).ok() {
- Some(s) => Ok(s.chars().next().unwrap()),
- None => Err(error)
- });
-
- try!(self.read_bytes(res.len_utf8() as u64));
- Ok(res)
- }
-
- fn read_str(&mut self) -> DecodingResult {
- let len = try!(self.read_usize());
- try!(self.read_bytes(len as u64));
-
- let mut buff = Vec::new();
- try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buff));
- match String::from_utf8(buff) {
- Ok(s) => Ok(s),
- Err(err) => Err(DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "error while decoding utf8 string",
- detail: Some(format!("Decoding error: {}", err))
- })),
- }
- }
- fn read_enum(&mut self, _: &str, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_enum_variant(&mut self, names: &[&str], mut f: F) -> DecodingResult
- where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult
- {
- let id = try!(self.read_u32());
- let id = id as usize;
- if id >= names.len() {
- Err(DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "out of bounds tag when reading enum variant",
- detail: Some(format!("Expected tag < {}, got {}", names.len(), id))
- }))
- } else {
- f(self, id)
- }
- }
- fn read_enum_variant_arg(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodingResult
- where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult
- {
- self.read_enum_variant(names, f)
- }
- fn read_enum_struct_variant_field(&mut self,
- _: &str,
- f_idx: usize,
- f: F)
- -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- self.read_enum_variant_arg(f_idx, f)
- }
- fn read_struct(&mut self, _: &str, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_struct_field(&mut self, _: &str, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_tuple(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_tuple_arg(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_tuple_struct(&mut self, _: &str, len: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- self.read_tuple(len, f)
- }
- fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- self.read_tuple_arg(a_idx, f)
- }
- fn read_option(&mut self, mut f: F) -> DecodingResult
- where F: FnMut(&mut DecoderReader<'a, R>, bool) -> DecodingResult
- {
- let x = try!(self.read_u8());
- match x {
- 1 => f(self, true),
- 0 => f(self, false),
- _ => Err(DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "invalid tag when decoding Option",
- detail: Some(format!("Expected 0 or 1, got {}", x))
- })),
- }
- }
- fn read_seq(&mut self, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult
- {
- let len = try!(self.read_usize());
- f(self, len)
- }
- fn read_seq_elt(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_map(&mut self, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult
- {
- let len = try!(self.read_usize());
- f(self, len)
- }
- fn read_map_elt_key(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn read_map_elt_val(&mut self, _: usize, f: F) -> DecodingResult
- where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
- {
- f(self)
- }
- fn error(&mut self, err: &str) -> DecodingError {
- DecodingError::InvalidEncoding(InvalidEncoding {
- desc: "user-induced error",
- detail: Some(err.to_string()),
- })
- }
-}
-
-static UTF8_CHAR_WIDTH: [u8; 256] = [
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
-0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
-4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
-];
-
-fn utf8_char_width(b: u8) -> usize {
- UTF8_CHAR_WIDTH[b as usize] as usize
-}
diff --git a/src/rustc_serialize/writer.rs b/src/rustc_serialize/writer.rs
deleted file mode 100644
index cb50a88..0000000
--- a/src/rustc_serialize/writer.rs
+++ /dev/null
@@ -1,429 +0,0 @@
-use std::io::Write;
-use std::io::Error as IoError;
-use std::io::ErrorKind as IoErrorKind;
-use std::error::Error;
-use std::fmt;
-
-use rustc_serialize_crate::Encoder;
-
-use byteorder::{BigEndian, WriteBytesExt};
-use byteorder::Error as ByteOrderError;
-
-pub type EncodingResult = Result;
-
-
-/// An error that can be produced during encoding.
-#[derive(Debug)]
-pub enum EncodingError {
- /// An error originating from the underlying `Writer`.
- IoError(IoError),
- /// An object could not be encoded with the given size limit.
- ///
- /// This error is returned before any bytes are written to the
- /// output `Writer`.
- SizeLimit,
-}
-
-/// An Encoder that encodes values directly into a Writer.
-///
-/// This struct should not be used often.
-/// For most cases, prefer the `encode_into` function.
-pub struct EncoderWriter<'a, W: 'a> {
- writer: &'a mut W,
-}
-
-pub struct SizeChecker {
- pub size_limit: u64,
- pub written: u64
-}
-
-fn wrap_io(err: ByteOrderError) -> EncodingError {
- match err {
- ByteOrderError::Io(ioe) => EncodingError::IoError(ioe),
- ByteOrderError::UnexpectedEOF => EncodingError::IoError(
- IoError::new(IoErrorKind::Other,
- "ByteOrder could not write to the buffer"))
- }
-}
-
-impl fmt::Display for EncodingError {
- fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- match *self {
- EncodingError::IoError(ref err) => write!(f, "IoError: {}", err),
- EncodingError::SizeLimit => write!(f, "SizeLimit")
- }
- }
-}
-
-impl Error for EncodingError {
- fn description(&self) -> &str {
- match *self {
- EncodingError::IoError(ref err) => Error::description(err),
- EncodingError::SizeLimit => "the size limit for decoding has been reached"
- }
- }
-
- fn cause(&self) -> Option<&Error> {
- match *self {
- EncodingError::IoError(ref err) => err.cause(),
- EncodingError::SizeLimit => None
- }
- }
-}
-
-impl <'a, W: Write> EncoderWriter<'a, W> {
- pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> {
- EncoderWriter {
- writer: w,
- }
- }
-}
-
-impl SizeChecker {
- pub fn new(limit: u64) -> SizeChecker {
- SizeChecker {
- size_limit: limit,
- written: 0
- }
- }
-
- fn add_raw(&mut self, size: usize) -> EncodingResult<()> {
- self.written += size as u64;
- if self.written <= self.size_limit {
- Ok(())
- } else {
- Err(EncodingError::SizeLimit)
- }
- }
-
- fn add_value(&mut self, t: T) -> EncodingResult<()> {
- use std::mem::size_of_val;
- self.add_raw(size_of_val(&t))
- }
-}
-
-impl<'a, W: Write> Encoder for EncoderWriter<'a, W> {
- type Error = EncodingError;
-
- fn emit_nil(&mut self) -> EncodingResult<()> {
- Ok(())
- }
- fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
- self.emit_u64(v as u64)
- }
- fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
- self.writer.write_u64::(v).map_err(wrap_io)
- }
- fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
- self.writer.write_u32::(v).map_err(wrap_io)
- }
- fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
- self.writer.write_u16::(v).map_err(wrap_io)
- }
- fn emit_u8(&mut self, v: u8) -> EncodingResult<()> {
- self.writer.write_u8(v).map_err(wrap_io)
- }
- fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
- self.emit_i64(v as i64)
- }
- fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
- self.writer.write_i64::(v).map_err(wrap_io)
- }
- fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
- self.writer.write_i32::(v).map_err(wrap_io)
- }
- fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
- self.writer.write_i16::(v).map_err(wrap_io)
- }
- fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
- self.writer.write_i8(v).map_err(wrap_io)
- }
- fn emit_bool(&mut self, v: bool) -> EncodingResult<()> {
- self.writer.write_u8(if v {1} else {0}).map_err(wrap_io)
- }
- fn emit_f64(&mut self, v: f64) -> EncodingResult<()> {
- self.writer.write_f64::(v).map_err(wrap_io)
- }
- fn emit_f32(&mut self, v: f32) -> EncodingResult<()> {
- self.writer.write_f32::(v).map_err(wrap_io)
- }
- fn emit_char(&mut self, v: char) -> EncodingResult<()> {
- // TODO: change this back once unicode works
- //let mut cbuf = [0; 4];
- //let sz = v.encode_utf8(&mut cbuf[..]).unwrap_or(0);
- //let ptr = &cbuf[..sz];
- //self.writer.write_all(ptr).map_err(EncodingError::IoError)
-
- let mut inter = String::with_capacity(1);
- inter.push(v);
- self.writer.write_all(inter.as_bytes()).map_err(EncodingError::IoError)
- }
- fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
- try!(self.emit_usize(v.len()));
- self.writer.write_all(v.as_bytes()).map_err(EncodingError::IoError)
- }
- fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- let max_u32: u32 = ::std::u32::MAX;
- if v_id > (max_u32 as usize) {
- panic!("Variant tag doesn't fit in a u32")
- }
- try!(self.emit_u32(v_id as u32));
- f(self)
- }
- fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_struct_variant(&mut self,
- _: &str,
- _: usize,
- _: usize,
- f: F)
- -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_struct_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- self.emit_tuple(len, f)
- }
- fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- self.emit_tuple_arg(f_idx, f)
- }
- fn emit_option(&mut self, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_option_none(&mut self) -> EncodingResult<()> {
- self.writer.write_u8(0).map_err(wrap_io)
- }
- fn emit_option_some(&mut self, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- try!(self.writer.write_u8(1).map_err(wrap_io));
- f(self)
- }
- fn emit_seq(&mut self, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- try!(self.emit_usize(len));
- f(self)
- }
- fn emit_seq_elt(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_map(&mut self, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- try!(self.emit_usize(len));
- f(self)
- }
- fn emit_map_elt_key(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_map_elt_val(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
- {
- f(self)
- }
-
-}
-
-impl Encoder for SizeChecker {
- type Error = EncodingError;
-
- fn emit_nil(&mut self) -> EncodingResult<()> {
- Ok(())
- }
- fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
- self.add_value(v as u64)
- }
- fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_u8(&mut self, v: u8) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
- self.add_value(v as i64)
- }
- fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_bool(&mut self, _: bool) -> EncodingResult<()> {
- self.add_value(0 as u8)
- }
- fn emit_f64(&mut self, v: f64) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_f32(&mut self, v: f32) -> EncodingResult<()> {
- self.add_value(v)
- }
- fn emit_char(&mut self, v: char) -> EncodingResult<()> {
- self.add_raw(v.len_utf8())
- }
- fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
- try!(self.add_value(0 as u64));
- self.add_raw(v.len())
- }
- fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- try!(self.add_value(v_id as u32));
- f(self)
- }
- fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_struct_variant(&mut self,
- _: &str,
- _: usize,
- _: usize,
- f: F)
- -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_struct_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- self.emit_tuple(len, f)
- }
- fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- self.emit_tuple_arg(f_idx, f)
- }
- fn emit_option(&mut self, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_option_none(&mut self) -> EncodingResult<()> {
- self.add_value(0 as u8)
- }
- fn emit_option_some(&mut self, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- try!(self.add_value(1 as u8));
- f(self)
- }
- fn emit_seq(&mut self, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- try!(self.emit_usize(len));
- f(self)
- }
- fn emit_seq_elt(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_map(&mut self, len: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- try!(self.emit_usize(len));
- f(self)
- }
- fn emit_map_elt_key(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
- fn emit_map_elt_val(&mut self, _: usize, f: F) -> EncodingResult<()>
- where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
- {
- f(self)
- }
-
-}
diff --git a/src/serde/mod.rs b/src/serde/mod.rs
index 76f648a..9caeb0a 100644
--- a/src/serde/mod.rs
+++ b/src/serde/mod.rs
@@ -1,20 +1,19 @@
//! A collection of serialization and deserialization functions
-//! that use the `serde` crate for the serialazble and deserializable
+//! that use the `serde` crate for the serializable and deserializable
//! implementation.
use std::io::{Write, Read};
+use std::io::Error as IoError;
+use std::{error, fmt, result};
use ::SizeLimit;
+use byteorder::{ByteOrder};
pub use self::reader::{
Deserializer,
- DeserializeResult,
- DeserializeError,
};
pub use self::writer::{
Serializer,
- SerializeResult,
- SerializeError,
};
use self::writer::SizeChecker;
@@ -24,16 +23,104 @@ use serde_crate as serde;
mod reader;
mod writer;
+pub type Result = result::Result;
+
+/// An error that can be produced during (de)serializing.
+///
+/// If decoding from a Buffer, assume that the buffer has been left
+/// in an invalid state.
+pub type Error = Box;
+
+#[derive(Debug)]
+pub enum ErrorKind {
+ /// If the error stems from the reader/writer that is being used
+ /// during (de)serialization, that error will be stored and returned here.
+ IoError(IoError),
+ /// If the bytes in the reader are not decodable because of an invalid
+ /// encoding, this error will be returned. This error is only possible
+ /// if a stream is corrupted. A stream produced from `encode` or `encode_into`
+ /// should **never** produce an InvalidEncoding error.
+ InvalidEncoding{
+ desc: &'static str,
+ detail: Option
+ },
+ /// If (de)serializing a message takes more than the provided size limit, this
+ /// error is returned.
+ SizeLimit,
+ SequenceMustHaveLength,
+ Custom(String)
+}
+
+impl error::Error for ErrorKind {
+ fn description(&self) -> &str {
+ match *self {
+ ErrorKind::IoError(ref err) => error::Error::description(err),
+ ErrorKind::InvalidEncoding{desc, ..} => desc,
+ ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences",
+ ErrorKind::SizeLimit => "the size limit for decoding has been reached",
+ ErrorKind::Custom(ref msg) => msg,
+
+ }
+ }
+
+ fn cause(&self) -> Option<&error::Error> {
+ match *self {
+ ErrorKind::IoError(ref err) => err.cause(),
+ ErrorKind::InvalidEncoding{..} => None,
+ ErrorKind::SequenceMustHaveLength => None,
+ ErrorKind::SizeLimit => None,
+ ErrorKind::Custom(_) => None,
+ }
+ }
+}
+
+impl From for Error {
+ fn from(err: IoError) -> Error {
+ ErrorKind::IoError(err).into()
+ }
+}
+
+impl fmt::Display for ErrorKind {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ ErrorKind::IoError(ref ioerr) =>
+ write!(fmt, "IoError: {}", ioerr),
+ ErrorKind::InvalidEncoding{desc, detail: None}=>
+ write!(fmt, "InvalidEncoding: {}", desc),
+ ErrorKind::InvalidEncoding{desc, detail: Some(ref detail)}=>
+ write!(fmt, "InvalidEncoding: {} ({})", desc, detail),
+ ErrorKind::SequenceMustHaveLength =>
+ write!(fmt, "Bincode can only encode sequences and maps that have a knowable size ahead of time."),
+ ErrorKind::SizeLimit =>
+ write!(fmt, "SizeLimit"),
+ ErrorKind::Custom(ref s) =>
+ s.fmt(fmt),
+ }
+ }
+}
+
+impl serde::de::Error for Error {
+ fn custom(desc: T) -> Error {
+ ErrorKind::Custom(desc.to_string()).into()
+ }
+}
+
+impl serde::ser::Error for Error {
+ fn custom(msg: T) -> Self {
+ ErrorKind::Custom(msg.to_string()).into()
+ }
+}
+
/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
-/// If this returns an `SerializeError` (other than SizeLimit), assume that the
+/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
-pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> SerializeResult<()>
- where W: Write, T: serde::Serialize,
+pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) -> Result<()>
+ where W: Write, T: serde::Serialize, E: ByteOrder
{
match size_limit {
SizeLimit::Infinite => { }
@@ -43,7 +130,7 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) ->
}
}
- let mut serializer = Serializer::new(writer);
+ let mut serializer = Serializer::<_, E>::new(writer);
serde::Serialize::serialize(value, &mut serializer)
}
@@ -51,24 +138,21 @@ pub fn serialize_into(writer: &mut W, value: &T, size_limit: SizeLimit) ->
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
-pub fn serialize(value: &T, size_limit: SizeLimit) -> SerializeResult>
- where T: serde::Serialize,
+pub fn serialize(value: &T, size_limit: SizeLimit) -> Result>
+ where T: serde::Serialize
{
// Since we are putting values directly into a vector, we can do size
// computation out here and pre-allocate a buffer of *exactly*
// the right size.
let mut writer = match size_limit {
SizeLimit::Bounded(size_limit) => {
- let actual_size = match serialized_size_bounded(value, size_limit) {
- Some(actual_size) => actual_size,
- None => { return Err(SerializeError::SizeLimit); }
- };
+ let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(ErrorKind::SizeLimit));
Vec::with_capacity(actual_size as usize)
}
SizeLimit::Infinite => Vec::new()
};
- try!(serialize_into(&mut writer, value, SizeLimit::Infinite));
+ try!(serialize_into::<_, _, E>(&mut writer, value, SizeLimit::Infinite));
Ok(writer)
}
@@ -76,7 +160,9 @@ pub fn serialize(value: &T, size_limit: SizeLimit) -> SerializeResult
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
-pub fn serialized_size(value: &T) -> u64 {
+pub fn serialized_size(value: &T) -> u64
+ where T: serde::Serialize
+{
use std::u64::MAX;
let mut size_checker = SizeChecker::new(MAX);
value.serialize(&mut size_checker).ok();
@@ -88,7 +174,9 @@ pub fn serialized_size(value: &T) -> u64 {
///
/// If it can be serialized in `max` or fewer bytes, that number will be returned
/// inside `Some`. If it goes over bounds, then None is returned.
-pub fn serialized_size_bounded(value: &T, max: u64) -> Option {
+pub fn serialized_size_bounded(value: &T, max: u64) -> Option
+ where T: serde::Serialize
+{
let mut size_checker = SizeChecker::new(max);
value.serialize(&mut size_checker).ok().map(|_| size_checker.written)
}
@@ -99,14 +187,14 @@ pub fn serialized_size_bounded(value: &T, max: u64) -> Opti
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
-/// If this returns an `DeserializeError`, assume that the buffer that you passed
+/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
-pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> DeserializeResult
+pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> Result
where R: Read,
T: serde::Deserialize,
{
- let mut deserializer = Deserializer::new(reader, size_limit);
+ let mut deserializer = Deserializer::<_, E>::new(reader, size_limit);
serde::Deserialize::deserialize(&mut deserializer)
}
@@ -114,10 +202,9 @@ pub fn deserialize_from(reader: &mut R, size_limit: SizeLimit) -> Deserial
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
-pub fn deserialize(bytes: &[u8]) -> DeserializeResult
+pub fn deserialize(bytes: &[u8]) -> Result
where T: serde::Deserialize,
{
let mut reader = bytes;
- deserialize_from(&mut reader, SizeLimit::Infinite)
+ deserialize_from::<_, _, E>(&mut reader, SizeLimit::Infinite)
}
-
diff --git a/src/serde/reader.rs b/src/serde/reader.rs
index f0a957c..8d6e2db 100644
--- a/src/serde/reader.rs
+++ b/src/serde/reader.rs
@@ -1,125 +1,12 @@
use std::io::Read;
-use std::io::Error as IoError;
-use std::error::Error;
-use std::fmt;
-use std::convert::From;
+use std::marker::PhantomData;
-use byteorder::Error as ByteOrderError;
-use byteorder::{BigEndian, ReadBytesExt};
-use num;
+use byteorder::{ReadBytesExt, ByteOrder};
use serde_crate as serde;
use serde_crate::de::value::ValueDeserializer;
-use serde_crate::de::Deserializer as SerdeDeserializer;
-
+use serde_crate::de::Error as DeError;
use ::SizeLimit;
-
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub struct InvalidEncoding {
- desc: &'static str,
- detail: Option,
-}
-
-impl fmt::Display for InvalidEncoding {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- InvalidEncoding { detail: None, desc } =>
- write!(fmt, "{}", desc),
- InvalidEncoding { detail: Some(ref detail), desc } =>
- write!(fmt, "{} ({})", desc, detail)
- }
- }
-}
-
-/// An error that can be produced during decoding.
-///
-/// If decoding from a Buffer, assume that the buffer has been left
-/// in an invalid state.
-#[derive(Debug)]
-pub enum DeserializeError {
- /// If the error stems from the reader that is being used
- /// during decoding, that error will be stored and returned here.
- IoError(IoError),
- /// If the bytes in the reader are not decodable because of an invalid
- /// encoding, this error will be returned. This error is only possible
- /// if a stream is corrupted. A stream produced from `encode` or `encode_into`
- /// should **never** produce an InvalidEncoding error.
- InvalidEncoding(InvalidEncoding),
- /// If decoding a message takes more than the provided size limit, this
- /// error is returned.
- SizeLimit,
- Serde(serde::de::value::Error)
-}
-
-impl Error for DeserializeError {
- fn description(&self) -> &str {
- match *self {
- DeserializeError::IoError(ref err) => Error::description(err),
- DeserializeError::InvalidEncoding(ref ib) => ib.desc,
- DeserializeError::SizeLimit => "the size limit for decoding has been reached",
- DeserializeError::Serde(ref s) => s.description(),
-
- }
- }
-
- fn cause(&self) -> Option<&Error> {
- match *self {
- DeserializeError::IoError(ref err) => err.cause(),
- DeserializeError::InvalidEncoding(_) => None,
- DeserializeError::SizeLimit => None,
- DeserializeError::Serde(ref s) => s.cause(),
- }
- }
-}
-
-impl From for DeserializeError {
- fn from(err: IoError) -> DeserializeError {
- DeserializeError::IoError(err)
- }
-}
-
-impl From for DeserializeError {
- fn from(err: ByteOrderError) -> DeserializeError {
- match err {
- ByteOrderError::Io(ioe) => DeserializeError::IoError(ioe),
- ByteOrderError::UnexpectedEOF => DeserializeError::Serde(
- serde::de::value::Error::EndOfStream),
- }
- }
-}
-
-impl From for DeserializeError {
- fn from(err: serde::de::value::Error) -> DeserializeError {
- DeserializeError::Serde(err)
- }
-}
-
-impl fmt::Display for DeserializeError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- DeserializeError::IoError(ref ioerr) =>
- write!(fmt, "IoError: {}", ioerr),
- DeserializeError::InvalidEncoding(ref ib) =>
- write!(fmt, "InvalidEncoding: {}", ib),
- DeserializeError::SizeLimit =>
- write!(fmt, "SizeLimit"),
- DeserializeError::Serde(ref s) =>
- s.fmt(fmt),
- }
- }
-}
-
-impl serde::de::Error for DeserializeError {
- fn custom>(desc: T) -> DeserializeError {
- DeserializeError::Serde(serde::de::value::Error::Custom(desc.into()))
- }
-
- fn end_of_stream() -> DeserializeError {
- DeserializeError::Serde(serde::de::value::Error::EndOfStream)
- }
-}
-
-pub type DeserializeResult = Result;
-
+use super::{Result, Error, ErrorKind};
/// A Deserializer that reads bytes from a buffer.
///
@@ -131,18 +18,20 @@ pub type DeserializeResult