From 7069ec3551a9b43843ddd6890f76ce27f00a9b08 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Thu, 20 Aug 2015 21:04:09 +0300 Subject: [PATCH 01/12] Encode: `FixedValueWriteError` now has pub value. --- src/encode.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encode.rs b/src/encode.rs index ef21c58c..6cd01dcd 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -70,7 +70,7 @@ impl From for MarkerWriteError { /// Represents an error that can occur when attempting to write MessagePack'ed single-byte value. #[derive(Debug)] -pub struct FixedValueWriteError(WriteError); +pub struct FixedValueWriteError(pub WriteError); impl Error for FixedValueWriteError { fn description(&self) -> &str { "error while writing MessagePack'ed single-byte value" } From 72a0dec062a09a1ca6309cac0a2af823f0cf626a Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Fri, 21 Aug 2015 22:23:18 +0300 Subject: [PATCH 02/12] Encode: make `write_sint_eff` public. --- src/encode.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encode.rs b/src/encode.rs index 6cd01dcd..b33709d9 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -537,7 +537,7 @@ pub fn write_sint(wr: &mut W, val: i64) -> Result } /// Encodes and attempts to write an `i64` value using the most effective representation. -fn write_sint_eff(wr: &mut W, val: i64) -> Result +pub fn write_sint_eff(wr: &mut W, val: i64) -> Result where W: Write { match val { From 4885a88fafd083504c322add3603a6da7b30e903 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Sat, 22 Aug 2015 23:23:18 +0300 Subject: [PATCH 03/12] API: move rustc_serialize bindings to its own crate. --- Cargo.toml | 1 - rmp-serialize/Cargo.toml | 14 + rmp-serialize/src/decode.rs | 342 ++++++++++++ rmp-serialize/src/encode.rs | 293 ++++++++++ rmp-serialize/src/lib.rs | 8 + rmp-serialize/tests/decoder.rs | 463 ++++++++++++++++ .../encode => rmp-serialize/tests}/encoder.rs | 8 +- rmp-serialize/tests/symmetric.rs | 35 ++ src/decode.rs | 351 +----------- src/encode.rs | 298 ----------- src/lib.rs | 4 - tests/func/decode/decoder.rs | 499 ------------------ tests/func/decode/mod.rs | 1 - tests/func/encode/mod.rs | 1 - tests/func/mod.rs | 1 - tests/func/rserialize.rs | 42 -- tests/lib.rs | 1 - 17 files changed, 1162 insertions(+), 1200 deletions(-) create mode 100644 rmp-serialize/Cargo.toml create mode 100644 rmp-serialize/src/decode.rs create mode 100644 rmp-serialize/src/encode.rs create mode 100644 rmp-serialize/src/lib.rs create mode 100644 rmp-serialize/tests/decoder.rs rename {tests/func/encode => rmp-serialize/tests}/encoder.rs (98%) create mode 100644 rmp-serialize/tests/symmetric.rs delete mode 100644 tests/func/decode/decoder.rs delete mode 100644 tests/func/rserialize.rs diff --git a/Cargo.toml b/Cargo.toml index a0c7c3cb..170094d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,5 @@ license = "MIT" [dependencies] byteorder = "*" -rustc-serialize = "0.3" serde = "*" serde_macros = { version = "*", optional = true } diff --git a/rmp-serialize/Cargo.toml b/rmp-serialize/Cargo.toml new file mode 100644 index 00000000..f0cc4bc4 --- /dev/null +++ b/rmp-serialize/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "rmp-serialize" +version = "0.6.0" +authors = ["Evgeny Safronov "] +license = "MIT" +description = "Rust Serialize bindings for RMP" +repository = "https://github.com/3Hren/msgpack-rust" +documentation = "https://3hren.github.io/msgpack-rust/rmp/index.html" +readme = "../README.md" +keywords = ["msgpack", "MessagePack", "serialization"] + +[dependencies] +rmp = { version = "*", path = ".." } +rustc-serialize = "0.3" diff --git a/rmp-serialize/src/decode.rs b/rmp-serialize/src/decode.rs new file mode 100644 index 00000000..fbfe5a87 --- /dev/null +++ b/rmp-serialize/src/decode.rs @@ -0,0 +1,342 @@ +use std::convert::From; +use std::fmt; +use std::io::Read; +use std::result; + +use serialize; + +use rmp::Marker; +use rmp::decode::{ + ReadError, + FixedValueReadError, + ValueReadError, + DecodeStringError, + read_nil, + read_bool, + read_u8_fit, + read_u16_fit, + read_u32_fit, + read_u64_fit, + read_i8_fit, + read_i16_fit, + read_i32_fit, + read_i64_fit, + read_f32, + read_f64, + read_str_len, + read_str_data, + read_array_size, + read_map_size, +}; + +/// Unstable: docs; incomplete +#[derive(Debug)] +pub enum Error { + /// The actual value type isn't equal with the expected one. + TypeMismatch(Marker), + InvalidMarkerRead(ReadError), + InvalidDataRead(ReadError), + LengthMismatch(u32), + /// Uncategorized error. + Uncategorized(String), +} + +impl ::std::error::Error for Error { + fn description(&self) -> &str { "error while decoding value" } + + fn cause(&self) -> Option<&::std::error::Error> { + use self::Error::*; + match *self { + TypeMismatch(_) => None, + InvalidMarkerRead(ref err) => Some(err), + InvalidDataRead(ref err) => Some(err), + LengthMismatch(_) => None, + Uncategorized(_) => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::std::error::Error::description(self).fmt(f) + } +} + +impl From for Error { + fn from(err: FixedValueReadError) -> Error { + match err { + FixedValueReadError::UnexpectedEOF => Error::InvalidMarkerRead(ReadError::UnexpectedEOF), + FixedValueReadError::Io(err) => Error::InvalidMarkerRead(ReadError::Io(err)), + FixedValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + } + } +} + +impl From for Error { + fn from(err: ValueReadError) -> Error { + match err { + ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), + ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), + } + } +} + +/// Unstable: docs; incomplete +impl<'a> From> for Error { + fn from(err: DecodeStringError) -> Error { + match err { + DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), + DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()), + DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()), + DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()), + DecodeStringError::InvalidDataCopy(..) => Error::Uncategorized("InvalidDataCopy".to_string()), + DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()), + } + } +} + +pub type Result = result::Result; + +/// # Note +/// +/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying +/// operation is retried. +// TODO: Docs. Examples. +pub struct Decoder { + rd: R, +} + +impl Decoder { + // TODO: Docs. + pub fn new(rd: R) -> Decoder { + Decoder { + rd: rd + } + } + + /// Gets a reference to the underlying reader in this decoder. + pub fn get_ref(&self) -> &R { + &self.rd + } + + /// Gets a mutable reference to the underlying reader in this decoder. + pub fn get_mut(&mut self) -> &mut R { + &mut self.rd + } + + /// Consumes this decoder returning the underlying reader. + pub fn into_inner(self) -> R { + self.rd + } +} + +/// Unstable: docs; examples; incomplete +impl serialize::Decoder for Decoder { + type Error = Error; + + fn read_nil(&mut self) -> Result<()> { + Ok(try!(read_nil(&mut self.rd))) + } + + fn read_bool(&mut self) -> Result { + Ok(try!(read_bool(&mut self.rd))) + } + + fn read_u8(&mut self) -> Result { + Ok(try!(read_u8_fit(&mut self.rd))) + } + + fn read_u16(&mut self) -> Result { + Ok(try!(read_u16_fit(&mut self.rd))) + } + + fn read_u32(&mut self) -> Result { + Ok(try!(read_u32_fit(&mut self.rd))) + } + + fn read_u64(&mut self) -> Result { + Ok(try!(read_u64_fit(&mut self.rd))) + } + + /// TODO: Doesn't look safe. + fn read_usize(&mut self) -> Result { + let v = try!(self.read_u64()); + Ok(v as usize) + } + + fn read_i8(&mut self) -> Result { + Ok(try!(read_i8_fit(&mut self.rd))) + } + + fn read_i16(&mut self) -> Result { + Ok(try!(read_i16_fit(&mut self.rd))) + } + + fn read_i32(&mut self) -> Result { + Ok(try!(read_i32_fit(&mut self.rd))) + } + + fn read_i64(&mut self) -> Result { + Ok(try!(read_i64_fit(&mut self.rd))) + } + + /// TODO: Doesn't look safe. + fn read_isize(&mut self) -> Result { + Ok(try!(self.read_i64()) as isize) + } + + fn read_f32(&mut self) -> Result { + Ok(try!(read_f32(&mut self.rd))) + } + + fn read_f64(&mut self) -> Result { + Ok(try!(read_f64(&mut self.rd))) + } + + fn read_char(&mut self) -> Result { + let mut res = try!(self.read_str()); + if res.len() == 1 { + Ok(res.pop().unwrap()) + } else { + Err(self.error("length mismatch")) + } + } + + fn read_str(&mut self) -> Result { + let len = try!(read_str_len(&mut self.rd)); + + let mut buf: Vec = (0..len).map(|_| 0u8).collect(); + + Ok(try!(read_str_data(&mut self.rd, len, &mut buf[..])).to_string()) + } + + fn read_enum(&mut self, _name: &str, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + let len = try!(read_array_size(&mut self.rd)); + if len == 2 { + f(self) + } else { + Err(self.error("sequence length mismatch")) + } + } + + fn read_enum_variant(&mut self, names: &[&str], mut f: F) -> Result + where F: FnMut(&mut Self, usize) -> Result + { + let id = try!(self.read_usize()); + + if id < names.len() { + try!(read_array_size(&mut self.rd)); + + f(self, id) + } else { + Err(self.error("variant type overflow")) + } + } + + fn read_enum_variant_arg(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result + where F: FnMut(&mut Self, usize) -> Result + { + self.read_enum_variant(names, f) + } + + fn read_enum_struct_variant_field(&mut self, _name: &str, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_struct(&mut self, _name: &str, len: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + self.read_tuple(len, f) + } + + fn read_struct_field(&mut self, _name: &str, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_tuple(&mut self, len: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + let actual = try!(read_array_size(&mut self.rd)); + + if len == actual as usize { + f(self) + } else { + Err(Error::LengthMismatch(actual)) + } + } + + // In case of MessagePack don't care about argument indexing. + fn read_tuple_arg(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_tuple_struct(&mut self, _name: &str, _len: usize, _f: F) -> Result + where F: FnOnce(&mut Self) -> Result { unimplemented!() } + fn read_tuple_struct_arg(&mut self, _idx: usize, _f: F) -> Result + where F: FnOnce(&mut Self) -> Result { unimplemented!() } + + /// We treat Value::Null as None. + fn read_option(&mut self, mut f: F) -> Result + where F: FnMut(&mut Self, bool) -> Result + { + // Primarily try to read optimisticly. + match f(self, true) { + Ok(val) => Ok(val), + Err(Error::TypeMismatch(Marker::Null)) => f(self, false), + Err(err) => Err(err) + } + } + + fn read_seq(&mut self, f: F) -> Result + where F: FnOnce(&mut Self, usize) -> Result + { + let len = try!(read_array_size(&mut self.rd)) as usize; + + f(self, len) + } + + fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_map(&mut self, f: F) -> Result + where F: FnOnce(&mut Self, usize) -> Result + { + let len = try!(read_map_size(&mut self.rd)) as usize; + + f(self, len) + } + + fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result + { + f(self) + } + + fn error(&mut self, err: &str) -> Error { + Error::Uncategorized(err.to_string()) + } +} diff --git a/rmp-serialize/src/encode.rs b/rmp-serialize/src/encode.rs new file mode 100644 index 00000000..756f9dc9 --- /dev/null +++ b/rmp-serialize/src/encode.rs @@ -0,0 +1,293 @@ +use std; +use std::io::Write; + +use serialize; + +use rmp::encode::{ + write_array_len, + write_bool, + write_f32, + write_f64, + write_map_len, + write_nil, + write_sint_eff, + write_str, + write_uint, +}; + +use rmp::encode::{ + FixedValueWriteError, + ValueWriteError, + WriteError, +}; + +#[derive(Debug)] +pub enum Error { + /// Failed to write MessagePack'ed single-byte value into the write. + InvalidFixedValueWrite(WriteError), + InvalidValueWrite(ValueWriteError), +} + +impl std::error::Error for Error { + fn description(&self) -> &str { "an error occurred while writing encoded value" } + + fn cause(&self) -> Option<&std::error::Error> { + match self { + &Error::InvalidFixedValueWrite(ref err) => Some(err), + &Error::InvalidValueWrite(ref err) => Some(err), + } + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::error::Error::description(self).fmt(f) + } +} + + +impl From for Error { + fn from(err: FixedValueWriteError) -> Error { + match err { + FixedValueWriteError(err) => Error::InvalidFixedValueWrite(err) + } + } +} + +impl From for Error { + fn from(err: ValueWriteError) -> Error { + Error::InvalidValueWrite(err) + } +} + +/// Represents MessagePack serialization implementation. +/// +/// # Note +/// +/// MessagePack has no specification about how to encode variant types. Thus we are free to do +/// whatever we want, so the given chose may be not ideal for you. +/// +/// Every Rust variant value can be represented as a tuple of index and a value. +/// +/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying +/// operation is retried. +// TODO: Docs. Examples, variant encoding policy. +pub struct Encoder<'a> { + wr: &'a mut Write, +} + +impl<'a> Encoder<'a> { + /// Creates a new MessagePack encoder whose output will be written to the writer specified. + pub fn new(wr: &'a mut Write) -> Encoder<'a> { + Encoder { + wr: wr, + } + } +} + +impl<'a> serialize::Encoder for Encoder<'a> { + type Error = Error; + + fn emit_nil(&mut self) -> Result<(), Error> { + write_nil(&mut self.wr).map_err(From::from) + } + + fn emit_bool(&mut self, val: bool) -> Result<(), Error> { + write_bool(&mut self.wr, val).map_err(From::from) + } + + fn emit_u8(&mut self, val: u8) -> Result<(), Error> { + self.emit_u64(val as u64) + } + + fn emit_u16(&mut self, val: u16) -> Result<(), Error> { + self.emit_u64(val as u64) + } + + fn emit_u32(&mut self, val: u32) -> Result<(), Error> { + self.emit_u64(val as u64) + } + + fn emit_u64(&mut self, val: u64) -> Result<(), Error> { + try!(write_uint(&mut self.wr, val)); + + Ok(()) + } + + fn emit_usize(&mut self, val: usize) -> Result<(), Error> { + self.emit_u64(val as u64) + } + + fn emit_i8(&mut self, val: i8) -> Result<(), Error> { + self.emit_i64(val as i64) + } + + fn emit_i16(&mut self, val: i16) -> Result<(), Error> { + self.emit_i64(val as i64) + } + + fn emit_i32(&mut self, val: i32) -> Result<(), Error> { + self.emit_i64(val as i64) + } + + fn emit_i64(&mut self, val: i64) -> Result<(), Error> { + try!(write_sint_eff(&mut self.wr, val)); + + Ok(()) + } + + fn emit_isize(&mut self, val: isize) -> Result<(), Error> { + self.emit_i64(val as i64) + } + + fn emit_f32(&mut self, val: f32) -> Result<(), Error> { + write_f32(&mut self.wr, val).map_err(From::from) + } + + fn emit_f64(&mut self, val: f64) -> Result<(), Error> { + write_f64(&mut self.wr, val).map_err(From::from) + } + + // TODO: The implementation involves heap allocation and is unstable. + fn emit_char(&mut self, val: char) -> Result<(), Error> { + let mut buf = String::new(); + buf.push(val); + self.emit_str(&buf) + } + + fn emit_str(&mut self, val: &str) -> Result<(), Error> { + write_str(&mut self.wr, val).map_err(From::from) + } + + /// Encodes and attempts to write the enum value into the Write. + /// + /// Currently we encode variant types as a tuple of id with array of args, like: [id, [args...]] + fn emit_enum(&mut self, _name: &str, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + // Mark that we want to encode a variant type. + try!(write_array_len(&mut self.wr, 2)); + + // Delegate to the encoder of a concrete value. + f(self) + } + + /// Encodes and attempts to write a concrete variant value. + fn emit_enum_variant(&mut self, _name: &str, id: usize, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + // Encode a value position... + try!(self.emit_usize(id)); + + // ... and its arguments length. + try!(write_array_len(&mut self.wr, len as u32)); + + // Delegate to the encoder of a value args. + f(self) + } + + /// Encodes and attempts to write a concrete variant value arguments. + fn emit_enum_variant_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_enum_struct_variant(&mut self, _name: &str, _id: usize, _len: usize, _f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + unimplemented!() + } + + fn emit_enum_struct_variant_field(&mut self, _name: &str, _idx: usize, _f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + unimplemented!() + } + + fn emit_struct(&mut self, _name: &str, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + self.emit_tuple(len, f) + } + + fn emit_struct_field(&mut self, _name: &str, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_tuple(&mut self, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + try!(write_array_len(&mut self.wr, len as u32)); + f(self) + } + + fn emit_tuple_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_tuple_struct(&mut self, _name: &str, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + self.emit_tuple(len, f) + } + + fn emit_tuple_struct_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_option(&mut self, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_option_none(&mut self) -> Result<(), Error> { + self.emit_nil() + } + + fn emit_option_some(&mut self, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + // TODO: Check len, overflow is possible. + fn emit_seq(&mut self, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + try!(write_array_len(&mut self.wr, len as u32)); + f(self) + } + + fn emit_seq_elt(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_map(&mut self, len: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + try!(write_map_len(&mut self.wr, len as u32)); + f(self) + } + + fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } + + fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> Result<(), Error> + where F: FnOnce(&mut Self) -> Result<(), Error> + { + f(self) + } +} diff --git a/rmp-serialize/src/lib.rs b/rmp-serialize/src/lib.rs new file mode 100644 index 00000000..63bd9a30 --- /dev/null +++ b/rmp-serialize/src/lib.rs @@ -0,0 +1,8 @@ +extern crate rmp; +extern crate rustc_serialize as serialize; + +pub mod decode; +pub mod encode; + +pub use decode::Decoder; +pub use encode::Encoder; diff --git a/rmp-serialize/tests/decoder.rs b/rmp-serialize/tests/decoder.rs new file mode 100644 index 00000000..a7ab9607 --- /dev/null +++ b/rmp-serialize/tests/decoder.rs @@ -0,0 +1,463 @@ +extern crate rmp as msgpack; +extern crate rmp_serialize; +extern crate rustc_serialize; + +use std::io::Cursor; +use std::result; + +use rustc_serialize::Decodable; + +use msgpack::Marker; +use rmp_serialize::Decoder; +use rmp_serialize::decode::Error; + +type Result = result::Result; + +#[test] +fn pass_null() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn fail_null_from_reserved() { + let buf = [0xc1]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + let res: Result<()> = Decodable::decode(&mut decoder); + match res.err() { + Some(Error::TypeMismatch(Marker::Reserved)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_bool() { + let buf = [0xc2, 0xc3]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(false, Decodable::decode(&mut decoder).ok().unwrap()); + assert_eq!(true, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn fail_bool_from_fixint() { + let buf = [0x00]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + let res: Result = Decodable::decode(&mut decoder); + match res.err() { + Some(Error::TypeMismatch(Marker::FixPos(0))) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_u64() { + let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(18446744073709551615u64, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_u32() { + let buf = [0xce, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(4294967295u32, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn fail_u32_from_u64() { + let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + let res: Result = Decodable::decode(&mut decoder); + match res.err() { + Some(Error::TypeMismatch(Marker::U64)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_u16() { + let buf = [0xcd, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(65535u16, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_u8() { + let buf = [0xcc, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(255u8, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_usize() { + let buf = [0xcc, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(255usize, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_i64() { + let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(9223372036854775807i64, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_i32() { + let buf = [0xd2, 0x7f, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(2147483647i32, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_i16() { + let buf = [0xd1, 0x7f, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(32767i16, Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_i8() { + let buf = [0xd0, 0x7f]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(127i8, Decodable::decode(&mut decoder).unwrap()); +} + +#[test] +fn pass_isize() { + let buf = [0xd0, 0x7f]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(127isize, Decodable::decode(&mut decoder).unwrap()); +} + +#[test] +fn pass_f32() { + let buf = [0xca, 0x7f, 0x7f, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(3.4028234e38_f32, Decodable::decode(&mut decoder).unwrap()); +} + +#[test] +fn pass_f64() { + let buf = [0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!(42f64, Decodable::decode(&mut decoder).unwrap()); +} + +#[test] +fn pass_string() { + let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: String = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!("le message".to_string(), actual); +} + +#[test] +fn pass_tuple() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: (u32, u32) = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!((42, 100500), actual); +} + +#[test] +fn fail_tuple_len_mismatch() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Result<(u32,)> = Decodable::decode(&mut decoder); + + match actual.err() { + Some(Error::LengthMismatch(2)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_tuple_struct() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + struct Decoded(u32, u32); + + let mut decoder = Decoder::new(cur); + let actual: Decoded = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(Decoded(42, 100500), actual); +} + +#[test] +fn pass_struct() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + struct Decoded { id: u32, value: u32 }; + + let mut decoder = Decoder::new(cur); + let actual: Decoded = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(Decoded { id: 42, value: 100500 }, actual); +} + +#[test] +fn pass_option_some() { + let buf = [0x1f]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Option = Decodable::decode(&mut decoder).unwrap(); + assert_eq!(Some(31), actual); +} + +#[test] +fn pass_option_some_null() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Option<()> = Decodable::decode(&mut decoder).unwrap(); + assert_eq!(Some(()), actual); +} + +#[test] +fn pass_option_none() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Option = Decodable::decode(&mut decoder).unwrap(); + assert_eq!(None, actual); +} + +#[test] +fn fail_option_u8_from_reserved() { + let buf = [0xc1]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Result> = Decodable::decode(&mut decoder); + match actual.err() { + Some(Error::TypeMismatch(Marker::Reserved)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_vector() { + let buf = [0x92, 0x00, 0xcc, 0x80]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: Vec = Decodable::decode(&mut decoder).unwrap(); + assert_eq!(vec![0, 128], actual); +} + +#[test] +fn pass_map() { + use std::collections::HashMap; + + let buf = [ + 0x82, // 2 (size) + 0xa3, 0x69, 0x6e, 0x74, // 'int' + 0xcc, 0x80, // 128 + 0xa3, 0x6b, 0x65, 0x79, // 'key' + 0x2a // 42 + ]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + let actual: HashMap = Decodable::decode(&mut decoder).unwrap(); + let mut expected = HashMap::new(); + expected.insert("int".to_string(), 128); + expected.insert("key".to_string(), 42); + + assert_eq!(expected, actual); +} + +#[test] +fn pass_enum() { + let buf = [0x92, 0x01, 0x90]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + enum Custom { + First, + Second, + } + + let mut decoder = Decoder::new(cur); + let actual: Custom = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(Custom::Second, actual); +} + +#[test] +fn pass_enum_variant_with_arg() { + let buf = [0x92, 0x01, 0x91, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + enum Custom { + First, + Second(u32), + } + + let mut decoder = Decoder::new(cur); + let actual: Custom = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(Custom::Second(42), actual); +} + +#[test] +fn fail_enum_sequence_mismatch() { + let buf = [0x93, 0x1, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + enum Custom { + First, + Second, + } + + let mut decoder = Decoder::new(cur); + let actual: Result = Decodable::decode(&mut decoder); + + match actual.err() { + Some(Error::Uncategorized(..)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn fail_enum_overflow() { + let buf = [0x92, 0x01, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + enum Custom { + First, + } + + let mut decoder = Decoder::new(cur); + let actual: Result = Decodable::decode(&mut decoder); + + match actual.err() { + Some(Error::Uncategorized(..)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_struct_enum_with_arg() { + let buf = [0x92, 0x01, 0x91, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, RustcDecodable)] + enum Custom { + First, + Second { id: u32 }, + } + + let mut decoder = Decoder::new(cur); + let actual: Custom = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(Custom::Second { id: 42 }, actual); +} + +#[test] +fn pass_decoder_get_ref() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); + assert_eq!(1, decoder.get_ref().position()); +} + +#[test] +fn pass_decoder_get_mut() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); + decoder.get_mut().set_position(0); + + assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); +} + +#[test] +fn pass_decoder_into_inner() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut decoder = Decoder::new(cur); + + assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); + let cur = decoder.into_inner(); + + assert_eq!(1, cur.position()); +} diff --git a/tests/func/encode/encoder.rs b/rmp-serialize/tests/encoder.rs similarity index 98% rename from tests/func/encode/encoder.rs rename to rmp-serialize/tests/encoder.rs index 34cc9f79..e23325fc 100644 --- a/tests/func/encode/encoder.rs +++ b/rmp-serialize/tests/encoder.rs @@ -1,9 +1,9 @@ -use std::io::Cursor; +extern crate rmp_serialize; +extern crate rustc_serialize; use rustc_serialize::Encodable; -use msgpack::Encoder; -use msgpack::encode::serialize::Error; +use rmp_serialize::encode::{Encoder, Error}; #[test] fn pass_null() { @@ -29,6 +29,8 @@ fn fail_null() { #[test] fn pass_bool() { + use std::io::Cursor; + let mut buf = [0x00, 0x00]; { diff --git a/rmp-serialize/tests/symmetric.rs b/rmp-serialize/tests/symmetric.rs new file mode 100644 index 00000000..b66395d3 --- /dev/null +++ b/rmp-serialize/tests/symmetric.rs @@ -0,0 +1,35 @@ +extern crate rmp_serialize; +extern crate rustc_serialize; + +use rustc_serialize::Decodable; +use rustc_serialize::Encodable; + +use rmp_serialize::Decoder; +use rmp_serialize::Encoder; + +#[test] +fn pass_symmetric_0i32() { + let val = 0i32; + let mut buf = Vec::new(); + + val.encode(&mut Encoder::new(&mut buf)).unwrap(); + let mut decoder = Decoder::new(&buf[..]); + + let res: i32 = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(val, res); +} + +#[test] +fn pass_generalized_integer_decoding() { + // Note, that we encode the value as `i64` and decode it as `u16`. + let val = 10050i64; + let mut buf = Vec::new(); + + val.encode(&mut Encoder::new(&mut buf)).unwrap(); + let mut decoder = Decoder::new(&buf[..]); + + let res: u16 = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(val, res as i64); +} diff --git a/src/decode.rs b/src/decode.rs index 4db3a67b..928437fd 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -898,7 +898,7 @@ use super::value::Integer; macro_rules! make_read_int_fit { ($name:ident, $ty:ty) => { #[allow(unused_comparisons)] - fn $name(rd: &mut R) -> Result<$ty, ValueReadError> + pub fn $name(rd: &mut R) -> Result<$ty, ValueReadError> where R: Read { let marker = try!(read_marker(rd)); @@ -1078,7 +1078,7 @@ pub fn read_str<'r, R>(rd: &mut R, mut buf: &'r mut [u8]) -> Result<&'r str, Dec read_str_data(rd, len, &mut buf[0..ulen]) } -fn read_str_data<'r, R>(rd: &mut R, len: u32, buf: &'r mut[u8]) -> Result<&'r str, DecodeStringError<'r>> +pub fn read_str_data<'r, R>(rd: &mut R, len: u32, buf: &'r mut[u8]) -> Result<&'r str, DecodeStringError<'r>> where R: Read { debug_assert_eq!(len as usize, buf.len()); @@ -1702,353 +1702,6 @@ pub fn read_value(rd: &mut R) -> Result } // mod value -pub mod serialize { - -use std::convert::From; -use std::fmt; -use std::io::Read; -use std::result; - -use serialize; - -use super::super::Marker; -use super::{ - ReadError, - FixedValueReadError, - ValueReadError, - DecodeStringError, - read_nil, - read_bool, - read_u8_fit, - read_u16_fit, - read_u32_fit, - read_u64_fit, - read_i8_fit, - read_i16_fit, - read_i32_fit, - read_i64_fit, - read_f32, - read_f64, - read_str_len, - read_str_data, - read_array_size, - read_map_size, -}; - -/// Unstable: docs; incomplete -#[derive(Debug)] -pub enum Error { - /// The actual value type isn't equal with the expected one. - TypeMismatch(Marker), - InvalidMarkerRead(ReadError), - InvalidDataRead(ReadError), - LengthMismatch(u32), - /// Uncategorized error. - Uncategorized(String), -} - -impl ::std::error::Error for Error { - fn description(&self) -> &str { "error while decoding value" } - - fn cause(&self) -> Option<&::std::error::Error> { - use self::Error::*; - match *self { - TypeMismatch(_) => None, - InvalidMarkerRead(ref err) => Some(err), - InvalidDataRead(ref err) => Some(err), - LengthMismatch(_) => None, - Uncategorized(_) => None, - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::std::error::Error::description(self).fmt(f) - } -} - -impl From for Error { - fn from(err: FixedValueReadError) -> Error { - match err { - FixedValueReadError::UnexpectedEOF => Error::InvalidMarkerRead(ReadError::UnexpectedEOF), - FixedValueReadError::Io(err) => Error::InvalidMarkerRead(ReadError::Io(err)), - FixedValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), - } - } -} - -impl From for Error { - fn from(err: ValueReadError) -> Error { - match err { - ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), - ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), - } - } -} - -/// Unstable: docs; incomplete -impl<'a> From> for Error { - fn from(err: DecodeStringError) -> Error { - match err { - DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()), - DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()), - DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()), - DecodeStringError::InvalidDataCopy(..) => Error::Uncategorized("InvalidDataCopy".to_string()), - DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()), - } - } -} - -pub type Result = result::Result; - -/// # Note -/// -/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying -/// operation is retried. -// TODO: Docs. Examples. -pub struct Decoder { - rd: R, -} - -impl Decoder { - // TODO: Docs. - pub fn new(rd: R) -> Decoder { - Decoder { - rd: rd - } - } - - /// Gets a reference to the underlying reader in this decoder. - pub fn get_ref(&self) -> &R { - &self.rd - } - - /// Gets a mutable reference to the underlying reader in this decoder. - pub fn get_mut(&mut self) -> &mut R { - &mut self.rd - } - - /// Consumes this decoder returning the underlying reader. - pub fn into_inner(self) -> R { - self.rd - } -} - -/// Unstable: docs; examples; incomplete -impl serialize::Decoder for Decoder { - type Error = Error; - - fn read_nil(&mut self) -> Result<()> { - Ok(try!(read_nil(&mut self.rd))) - } - - fn read_bool(&mut self) -> Result { - Ok(try!(read_bool(&mut self.rd))) - } - - fn read_u8(&mut self) -> Result { - Ok(try!(read_u8_fit(&mut self.rd))) - } - - fn read_u16(&mut self) -> Result { - Ok(try!(read_u16_fit(&mut self.rd))) - } - - fn read_u32(&mut self) -> Result { - Ok(try!(read_u32_fit(&mut self.rd))) - } - - fn read_u64(&mut self) -> Result { - Ok(try!(read_u64_fit(&mut self.rd))) - } - - /// TODO: Doesn't look safe. - fn read_usize(&mut self) -> Result { - let v = try!(self.read_u64()); - Ok(v as usize) - } - - fn read_i8(&mut self) -> Result { - Ok(try!(read_i8_fit(&mut self.rd))) - } - - fn read_i16(&mut self) -> Result { - Ok(try!(read_i16_fit(&mut self.rd))) - } - - fn read_i32(&mut self) -> Result { - Ok(try!(read_i32_fit(&mut self.rd))) - } - - fn read_i64(&mut self) -> Result { - Ok(try!(read_i64_fit(&mut self.rd))) - } - - /// TODO: Doesn't look safe. - fn read_isize(&mut self) -> Result { - Ok(try!(self.read_i64()) as isize) - } - - fn read_f32(&mut self) -> Result { - Ok(try!(read_f32(&mut self.rd))) - } - - fn read_f64(&mut self) -> Result { - Ok(try!(read_f64(&mut self.rd))) - } - - fn read_char(&mut self) -> Result { - let mut res = try!(self.read_str()); - if res.len() == 1 { - Ok(res.pop().unwrap()) - } else { - Err(self.error("length mismatch")) - } - } - - fn read_str(&mut self) -> Result { - let len = try!(read_str_len(&mut self.rd)); - - let mut buf: Vec = (0..len).map(|_| 0u8).collect(); - - Ok(try!(read_str_data(&mut self.rd, len, &mut buf[..])).to_string()) - } - - fn read_enum(&mut self, _name: &str, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - let len = try!(read_array_size(&mut self.rd)); - if len == 2 { - f(self) - } else { - Err(self.error("sequence length mismatch")) - } - } - - fn read_enum_variant(&mut self, names: &[&str], mut f: F) -> Result - where F: FnMut(&mut Self, usize) -> Result - { - let id = try!(self.read_usize()); - - if id < names.len() { - try!(read_array_size(&mut self.rd)); - - f(self, id) - } else { - Err(self.error("variant type overflow")) - } - } - - fn read_enum_variant_arg(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result - where F: FnMut(&mut Self, usize) -> Result - { - self.read_enum_variant(names, f) - } - - fn read_enum_struct_variant_field(&mut self, _name: &str, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_struct(&mut self, _name: &str, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - self.read_tuple(len, f) - } - - fn read_struct_field(&mut self, _name: &str, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_tuple(&mut self, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - let actual = try!(read_array_size(&mut self.rd)); - - if len == actual as usize { - f(self) - } else { - Err(Error::LengthMismatch(actual)) - } - } - - // In case of MessagePack don't care about argument indexing. - fn read_tuple_arg(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_tuple_struct(&mut self, _name: &str, _len: usize, _f: F) -> Result - where F: FnOnce(&mut Self) -> Result { unimplemented!() } - fn read_tuple_struct_arg(&mut self, _idx: usize, _f: F) -> Result - where F: FnOnce(&mut Self) -> Result { unimplemented!() } - - /// We treat Value::Null as None. - fn read_option(&mut self, mut f: F) -> Result - where F: FnMut(&mut Self, bool) -> Result - { - // Primarily try to read optimisticly. - match f(self, true) { - Ok(val) => Ok(val), - Err(Error::TypeMismatch(Marker::Null)) => f(self, false), - Err(err) => Err(err) - } - } - - fn read_seq(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result - { - let len = try!(read_array_size(&mut self.rd)) as usize; - - f(self, len) - } - - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_map(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result - { - let len = try!(read_map_size(&mut self.rd)) as usize; - - f(self, len) - } - - fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result - { - f(self) - } - - fn error(&mut self, err: &str) -> Error { - Error::Uncategorized(err.to_string()) - } -} - -} - pub mod serde { use std::convert::From; diff --git a/src/encode.rs b/src/encode.rs index b33709d9..e722f756 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -901,304 +901,6 @@ pub fn write_value(wr: &mut W, val: &Value) -> Result<(), Error> } // mod value -pub mod serialize { - -use serialize; - -use std::fmt; -use std::io::Write; - -use super::{ - write_nil, - write_bool, - write_uint, - write_sint_eff, - write_f32, - write_f64, - write_str, - write_array_len, - write_map_len, -}; - -use super::{ - WriteError, - FixedValueWriteError, - ValueWriteError, -}; - -#[derive(Debug)] -pub enum Error { - /// Failed to write MessagePack'ed single-byte value into the write. - InvalidFixedValueWrite(WriteError), - InvalidValueWrite(ValueWriteError), -} - -impl ::std::error::Error for Error { - fn description(&self) -> &str { "an error occurred while writing encoded value" } - - fn cause(&self) -> Option<&::std::error::Error> { - match *self { - Error::InvalidFixedValueWrite(ref err) => Some(err), - Error::InvalidValueWrite(ref err) => Some(err), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::std::error::Error::description(self).fmt(f) - } -} - - -impl From for Error { - fn from(err: FixedValueWriteError) -> Error { - match err { - FixedValueWriteError(err) => Error::InvalidFixedValueWrite(err) - } - } -} - -impl From for Error { - fn from(err: ValueWriteError) -> Error { - Error::InvalidValueWrite(err) - } -} - -/// Represents MessagePack serialization implementation. -/// -/// # Note -/// -/// MessagePack has no specification about how to encode variant types. Thus we are free to do -/// whatever we want, so the given chose may be not ideal for you. -/// -/// Every Rust variant value can be represented as a tuple of index and a value. -/// -/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying -/// operation is retried. -// TODO: Docs. Examples, variant encoding policy. -pub struct Encoder<'a> { - wr: &'a mut Write, -} - -impl<'a> Encoder<'a> { - /// Creates a new MessagePack encoder whose output will be written to the writer specified. - pub fn new(wr: &'a mut Write) -> Encoder<'a> { - Encoder { - wr: wr, - } - } -} - -impl<'a> serialize::Encoder for Encoder<'a> { - type Error = Error; - - fn emit_nil(&mut self) -> Result<(), Error> { - write_nil(&mut self.wr).map_err(From::from) - } - - fn emit_bool(&mut self, val: bool) -> Result<(), Error> { - write_bool(&mut self.wr, val).map_err(From::from) - } - - fn emit_u8(&mut self, val: u8) -> Result<(), Error> { - self.emit_u64(val as u64) - } - - fn emit_u16(&mut self, val: u16) -> Result<(), Error> { - self.emit_u64(val as u64) - } - - fn emit_u32(&mut self, val: u32) -> Result<(), Error> { - self.emit_u64(val as u64) - } - - fn emit_u64(&mut self, val: u64) -> Result<(), Error> { - try!(write_uint(&mut self.wr, val)); - - Ok(()) - } - - fn emit_usize(&mut self, val: usize) -> Result<(), Error> { - self.emit_u64(val as u64) - } - - fn emit_i8(&mut self, val: i8) -> Result<(), Error> { - self.emit_i64(val as i64) - } - - fn emit_i16(&mut self, val: i16) -> Result<(), Error> { - self.emit_i64(val as i64) - } - - fn emit_i32(&mut self, val: i32) -> Result<(), Error> { - self.emit_i64(val as i64) - } - - fn emit_i64(&mut self, val: i64) -> Result<(), Error> { - try!(write_sint_eff(&mut self.wr, val)); - - Ok(()) - } - - fn emit_isize(&mut self, val: isize) -> Result<(), Error> { - self.emit_i64(val as i64) - } - - fn emit_f32(&mut self, val: f32) -> Result<(), Error> { - write_f32(&mut self.wr, val).map_err(From::from) - } - - fn emit_f64(&mut self, val: f64) -> Result<(), Error> { - write_f64(&mut self.wr, val).map_err(From::from) - } - - // TODO: The implementation involves heap allocation and is unstable. - fn emit_char(&mut self, val: char) -> Result<(), Error> { - let mut buf = String::new(); - buf.push(val); - self.emit_str(&buf) - } - - fn emit_str(&mut self, val: &str) -> Result<(), Error> { - write_str(&mut self.wr, val).map_err(From::from) - } - - /// Encodes and attempts to write the enum value into the Write. - /// - /// Currently we encode variant types as a tuple of id with array of args, like: [id, [args...]] - fn emit_enum(&mut self, _name: &str, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - // Mark that we want to encode a variant type. - try!(write_array_len(&mut self.wr, 2)); - - // Delegate to the encoder of a concrete value. - f(self) - } - - /// Encodes and attempts to write a concrete variant value. - fn emit_enum_variant(&mut self, _name: &str, id: usize, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - // Encode a value position... - try!(self.emit_usize(id)); - - // ... and its arguments length. - try!(write_array_len(&mut self.wr, len as u32)); - - // Delegate to the encoder of a value args. - f(self) - } - - /// Encodes and attempts to write a concrete variant value arguments. - fn emit_enum_variant_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_enum_struct_variant(&mut self, _name: &str, _id: usize, _len: usize, _f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - unimplemented!() - } - - fn emit_enum_struct_variant_field(&mut self, _name: &str, _idx: usize, _f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - unimplemented!() - } - - fn emit_struct(&mut self, _name: &str, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - self.emit_tuple(len, f) - } - - fn emit_struct_field(&mut self, _name: &str, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_tuple(&mut self, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - try!(write_array_len(&mut self.wr, len as u32)); - f(self) - } - - fn emit_tuple_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_tuple_struct(&mut self, _name: &str, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - self.emit_tuple(len, f) - } - - fn emit_tuple_struct_arg(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_option(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_option_none(&mut self) -> Result<(), Error> { - self.emit_nil() - } - - fn emit_option_some(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - // TODO: Check len, overflow is possible. - fn emit_seq(&mut self, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - try!(write_array_len(&mut self.wr, len as u32)); - f(self) - } - - fn emit_seq_elt(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_map(&mut self, len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - try!(write_map_len(&mut self.wr, len as u32)); - f(self) - } - - fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } - - fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Self) -> Result<(), Error> - { - f(self) - } -} - -} - pub mod serde { use serde; diff --git a/src/lib.rs b/src/lib.rs index 5c1cb625..685e9b81 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -122,7 +122,6 @@ //! ``` extern crate byteorder; -extern crate rustc_serialize as serialize; extern crate serde; @@ -135,9 +134,6 @@ pub mod value; pub const MSGPACK_VERSION : u32 = 5; -pub use decode::serialize::Decoder; -pub use encode::serialize::Encoder; - pub use decode::serde::Deserializer; pub use encode::serde::Serializer; diff --git a/tests/func/decode/decoder.rs b/tests/func/decode/decoder.rs deleted file mode 100644 index 53f08683..00000000 --- a/tests/func/decode/decoder.rs +++ /dev/null @@ -1,499 +0,0 @@ -mod null { - use std::io::Cursor; - - use rustc_serialize::Decodable; - - use msgpack::Decoder; - - #[test] - fn pass() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); - } - - mod fail { - use std::io::Cursor; - use std::result; - - use rustc_serialize::Decodable; - - use msgpack::Decoder; - use msgpack::Marker; - use msgpack::decode::serialize::Error; - - type Result = result::Result; - - #[test] - fn from_reserved() { - let buf = [0xc1]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - let res: Result<()> = Decodable::decode(&mut decoder); - match res.err() { - Some(Error::TypeMismatch(Marker::Reserved)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - } // mod fail -} // mod null - -mod bool { - use std::io::Cursor; - - use rustc_serialize::Decodable; - - use msgpack::Decoder; - - #[test] - fn pass() { - let buf = [0xc2, 0xc3]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(false, Decodable::decode(&mut decoder).ok().unwrap()); - assert_eq!(true, Decodable::decode(&mut decoder).ok().unwrap()); - } - - mod fail { - use std::io::Cursor; - use std::result; - - use rustc_serialize::Decodable; - - use msgpack::Decoder; - use msgpack::Marker; - use msgpack::decode::serialize::Error; - - type Result = result::Result; - - #[test] - fn from_fixint() { - let buf = [0x00]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - let res: Result = Decodable::decode(&mut decoder); - match res.err() { - Some(Error::TypeMismatch(Marker::FixPos(0))) => (), - other => panic!("unexpected result: {:?}", other) - } - } - } -} - -mod unspecified { - use std::io::Cursor; - use std::result; - - use rustc_serialize::Decodable; - - use msgpack::Decoder; - use msgpack::Marker; - use msgpack::decode::serialize::Error; - - type Result = result::Result; - - #[test] - fn pass_u64() { - let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(18446744073709551615u64, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_u32() { - let buf = [0xce, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(4294967295u32, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn fail_u32_from_u64() { - let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - let res: Result = Decodable::decode(&mut decoder); - match res.err() { - Some(Error::TypeMismatch(Marker::U64)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_u16() { - let buf = [0xcd, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(65535u16, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_u8() { - let buf = [0xcc, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(255u8, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_usize() { - let buf = [0xcc, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(255usize, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_i64() { - let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(9223372036854775807i64, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_i32() { - let buf = [0xd2, 0x7f, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(2147483647i32, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_i16() { - let buf = [0xd1, 0x7f, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(32767i16, Decodable::decode(&mut decoder).ok().unwrap()); - } - - #[test] - fn pass_i8() { - let buf = [0xd0, 0x7f]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(127i8, Decodable::decode(&mut decoder).unwrap()); - } - - #[test] - fn pass_isize() { - let buf = [0xd0, 0x7f]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(127isize, Decodable::decode(&mut decoder).unwrap()); - } - - #[test] - fn pass_f32() { - let buf = [0xca, 0x7f, 0x7f, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(3.4028234e38_f32, Decodable::decode(&mut decoder).unwrap()); - } - - #[test] - fn pass_f64() { - let buf = [0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!(42f64, Decodable::decode(&mut decoder).unwrap()); - } - - #[test] - fn pass_string() { - let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: String = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!("le message".to_string(), actual); - } - - #[test] - fn pass_tuple() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: (u32, u32) = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!((42, 100500), actual); - } - - #[test] - fn fail_tuple_len_mismatch() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Result<(u32,)> = Decodable::decode(&mut decoder); - - match actual.err() { - Some(Error::LengthMismatch(2)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_tuple_struct() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - struct Decoded(u32, u32); - - let mut decoder = Decoder::new(cur); - let actual: Decoded = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(Decoded(42, 100500), actual); - } - - #[test] - fn pass_struct() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - struct Decoded { id: u32, value: u32 }; - - let mut decoder = Decoder::new(cur); - let actual: Decoded = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(Decoded { id: 42, value: 100500 }, actual); - } - - #[test] - fn pass_option_some() { - let buf = [0x1f]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Option = Decodable::decode(&mut decoder).unwrap(); - assert_eq!(Some(31), actual); - } - - #[test] - fn pass_option_some_null() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Option<()> = Decodable::decode(&mut decoder).unwrap(); - assert_eq!(Some(()), actual); - } - - #[test] - fn pass_option_none() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Option = Decodable::decode(&mut decoder).unwrap(); - assert_eq!(None, actual); - } - - #[test] - fn fail_option_u8_from_reserved() { - let buf = [0xc1]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Result> = Decodable::decode(&mut decoder); - match actual.err() { - Some(Error::TypeMismatch(Marker::Reserved)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_vector() { - let buf = [0x92, 0x00, 0xcc, 0x80]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: Vec = Decodable::decode(&mut decoder).unwrap(); - assert_eq!(vec![0, 128], actual); - } - - #[test] - fn pass_map() { - use std::collections::HashMap; - - let buf = [ - 0x82, // 2 (size) - 0xa3, 0x69, 0x6e, 0x74, // 'int' - 0xcc, 0x80, // 128 - 0xa3, 0x6b, 0x65, 0x79, // 'key' - 0x2a // 42 - ]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - let actual: HashMap = Decodable::decode(&mut decoder).unwrap(); - let mut expected = HashMap::new(); - expected.insert("int".to_string(), 128); - expected.insert("key".to_string(), 42); - - assert_eq!(expected, actual); - } - - #[test] - fn pass_enum() { - let buf = [0x92, 0x01, 0x90]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - enum Custom { - First, - Second, - } - - let mut decoder = Decoder::new(cur); - let actual: Custom = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(Custom::Second, actual); - } - - #[test] - fn pass_enum_variant_with_arg() { - let buf = [0x92, 0x01, 0x91, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - enum Custom { - First, - Second(u32), - } - - let mut decoder = Decoder::new(cur); - let actual: Custom = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(Custom::Second(42), actual); - } - - #[test] - fn fail_enum_sequence_mismatch() { - let buf = [0x93, 0x1, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - enum Custom { - First, - Second, - } - - let mut decoder = Decoder::new(cur); - let actual: Result = Decodable::decode(&mut decoder); - - match actual.err() { - Some(Error::Uncategorized(..)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn fail_enum_overflow() { - let buf = [0x92, 0x01, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - enum Custom { - First, - } - - let mut decoder = Decoder::new(cur); - let actual: Result = Decodable::decode(&mut decoder); - - match actual.err() { - Some(Error::Uncategorized(..)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_struct_enum_with_arg() { - let buf = [0x92, 0x01, 0x91, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, RustcDecodable)] - enum Custom { - First, - Second { id: u32 }, - } - - let mut decoder = Decoder::new(cur); - let actual: Custom = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(Custom::Second { id: 42 }, actual); - } - - #[test] - fn pass_symmetric_0i32() { - use msgpack::Encoder; - use rustc_serialize::Encodable; - - let val = 0i32; - let mut buf = Vec::new(); - - val.encode(&mut Encoder::new(&mut buf)).unwrap(); - let mut decoder = Decoder::new(&buf[..]); - - let res: i32 = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(val, res); - } - - #[test] - fn pass_generalized_integer_decoding() { - use msgpack::Encoder; - use rustc_serialize::Encodable; - - // Note, that we encode the value as `i64` and decode it as `u16`. - let val = 10050i64; - let mut buf = Vec::new(); - - val.encode(&mut Encoder::new(&mut buf)).unwrap(); - let mut decoder = Decoder::new(&buf[..]); - - let res: u16 = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(val, res as i64); - } -} diff --git a/tests/func/decode/mod.rs b/tests/func/decode/mod.rs index 0532248a..66551409 100644 --- a/tests/func/decode/mod.rs +++ b/tests/func/decode/mod.rs @@ -10,7 +10,6 @@ mod map; mod ext; // High-level deserialize interface. -mod decoder; mod deserializer; mod value; mod value_ref; diff --git a/tests/func/encode/mod.rs b/tests/func/encode/mod.rs index 20539cac..c138c98d 100644 --- a/tests/func/encode/mod.rs +++ b/tests/func/encode/mod.rs @@ -10,7 +10,6 @@ mod map; mod ext; // High-level serialize interface. -mod encoder; mod serializer; mod value; mod value_ref; diff --git a/tests/func/mod.rs b/tests/func/mod.rs index 29695299..d6b65bc4 100644 --- a/tests/func/mod.rs +++ b/tests/func/mod.rs @@ -1,4 +1,3 @@ mod encode; mod decode; -mod rserialize; mod serde; diff --git a/tests/func/rserialize.rs b/tests/func/rserialize.rs deleted file mode 100644 index 21bbf130..00000000 --- a/tests/func/rserialize.rs +++ /dev/null @@ -1,42 +0,0 @@ -use std::io::Cursor; - -use rustc_serialize::Decodable; - -use msgpack::Decoder; - -#[test] -fn pass_decoder_get_ref() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); - assert_eq!(1, decoder.get_ref().position()); -} - -#[test] -fn pass_decoder_get_mut() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); - decoder.get_mut().set_position(0); - - assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); -} - -#[test] -fn pass_decoder_into_inner() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut decoder = Decoder::new(cur); - - assert_eq!((), Decodable::decode(&mut decoder).ok().unwrap()); - let cur = decoder.into_inner(); - - assert_eq!(1, cur.position()); -} diff --git a/tests/lib.rs b/tests/lib.rs index 0adbfb23..067d49f6 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -2,7 +2,6 @@ #![cfg_attr(feature = "serde_macros", plugin(serde_macros))] extern crate rmp as msgpack; -extern crate rustc_serialize; extern crate serde; mod func; From 93d36e56fdf68381614e6682f5e07690a4c5505e Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Sun, 23 Aug 2015 23:59:23 +0300 Subject: [PATCH 04/12] Examples: move serialize examples to its crate. --- rmp-serialize/src/lib.rs | 77 ++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 77 ---------------------------------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/rmp-serialize/src/lib.rs b/rmp-serialize/src/lib.rs index 63bd9a30..86c632f7 100644 --- a/rmp-serialize/src/lib.rs +++ b/rmp-serialize/src/lib.rs @@ -1,3 +1,80 @@ +//! ## Examples +//! +//! Let's try to encode a tuple of int and string. +//! +//! ```rust +//! extern crate rmp_serialize; +//! extern crate rustc_serialize; +//! +//! use rustc_serialize::Encodable; +//! use rmp_serialize::Encoder; +//! +//! fn main() { +//! let val = (42u8, "the Answer"); +//! +//! // The encoder borrows the bytearray buffer. +//! let mut buf = [0u8; 13]; +//! +//! val.encode(&mut Encoder::new(&mut &mut buf[..])); +//! +//! assert_eq!([0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf); +//! } +//! ``` +//! +//! Now we have an encoded buffer, which we can decode the same way: +//! +//! ```rust +//! extern crate rmp_serialize; +//! extern crate rustc_serialize; +//! +//! use rustc_serialize::Decodable; +//! use rmp_serialize::Decoder; +//! +//! fn main() { +//! let buf = [0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72]; +//! +//! let mut decoder = Decoder::new(&buf[..]); +//! +//! let res: (u8, String) = Decodable::decode(&mut decoder).unwrap(); +//! +//! assert_eq!((42u8, "the Answer".to_string()), res); +//! } +//! ``` +//! +//! RMP also allows to automatically serialize/deserialize custom structures using rustc_serialize +//! reflection. To enable this feature, derive RustcEncodable and RustcDecodable attributes as +//! shown in the following example: +//! +//! ```rust +//! extern crate rmp_serialize; +//! extern crate rustc_serialize; +//! +//! use rustc_serialize::{Encodable, Decodable}; +//! use rmp_serialize::{Encoder, Decoder}; +//! +//! #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] +//! struct Custom { +//! id: u32, +//! key: String, +//! } +//! +//! fn main() { +//! let val = Custom { id: 42u32, key: "the Answer".to_string() }; +//! +//! let mut buf = [0u8; 13]; +//! +//! val.encode(&mut Encoder::new(&mut &mut buf[..])); +//! +//! assert_eq!([0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf); +//! +//! // Now try to unpack the buffer into the initial struct. +//! let mut decoder = Decoder::new(&buf[..]); +//! let res: Custom = Decodable::decode(&mut decoder).ok().unwrap(); +//! +//! assert_eq!(val, res); +//! } +//! ``` + extern crate rmp; extern crate rustc_serialize as serialize; diff --git a/src/lib.rs b/src/lib.rs index 685e9b81..9762dfd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,83 +43,6 @@ //! //! This project is developed using TDD and CI, so any found bugs will be fixed without breaking //! existing functionality. -//! -//! ## Examples -//! -//! Let's try to encode a tuple of int and string. -//! -//! ```rust -//! extern crate rmp as msgpack; -//! extern crate rustc_serialize; -//! -//! use rustc_serialize::Encodable; -//! use msgpack::Encoder; -//! -//! fn main() { -//! let val = (42u8, "the Answer"); -//! -//! // The encoder borrows the bytearray buffer. -//! let mut buf = [0u8; 13]; -//! -//! val.encode(&mut Encoder::new(&mut &mut buf[..])); -//! -//! assert_eq!([0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf); -//! } -//! ``` -//! -//! Now we have an encoded buffer, which we can decode the same way: -//! -//! ```rust -//! extern crate rmp as msgpack; -//! extern crate rustc_serialize; -//! -//! use rustc_serialize::Decodable; -//! use msgpack::Decoder; -//! -//! fn main() { -//! let buf = [0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72]; -//! -//! let mut decoder = Decoder::new(&buf[..]); -//! -//! let res: (u8, String) = Decodable::decode(&mut decoder).unwrap(); -//! -//! assert_eq!((42u8, "the Answer".to_string()), res); -//! } -//! ``` -//! -//! RMP also allows to automatically serialize/deserialize custom structures using rustc_serialize -//! reflection. To enable this feature, derive RustcEncodable and RustcDecodable attributes as -//! shown in the following example: -//! -//! ```rust -//! extern crate rmp as msgpack; -//! extern crate rustc_serialize; -//! -//! use rustc_serialize::{Encodable, Decodable}; -//! use msgpack::{Encoder, Decoder}; -//! -//! #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] -//! struct Custom { -//! id: u32, -//! key: String, -//! } -//! -//! fn main() { -//! let val = Custom { id: 42u32, key: "the Answer".to_string() }; -//! -//! let mut buf = [0u8; 13]; -//! -//! val.encode(&mut Encoder::new(&mut &mut buf[..])); -//! -//! assert_eq!([0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72], buf); -//! -//! // Now try to unpack the buffer into the initial struct. -//! let mut decoder = Decoder::new(&buf[..]); -//! let res: Custom = Decodable::decode(&mut decoder).ok().unwrap(); -//! -//! assert_eq!(val, res); -//! } -//! ``` extern crate byteorder; From e2475b9e359e8475ee6c53ecd8b17f1fec256be1 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 00:16:41 +0300 Subject: [PATCH 05/12] API: move RMP into its own crate. --- rmp-serialize/Cargo.toml | 2 +- Cargo.toml => rmp/Cargo.toml | 13 +++---------- {benches => rmp/benches}/bench.rs | 0 {src => rmp/src}/decode.rs | 0 {src => rmp/src}/decode/value_ref.rs | 0 {src => rmp/src}/encode.rs | 0 {src => rmp/src}/encode/value_ref.rs | 0 {src => rmp/src}/init.rs | 0 {src => rmp/src}/lib.rs | 0 {src => rmp/src}/value.rs | 0 {tests => rmp/tests}/func/decode/array.rs | 0 {tests => rmp/tests}/func/decode/bin.rs | 0 {tests => rmp/tests}/func/decode/bool.rs | 0 {tests => rmp/tests}/func/decode/deserializer.rs | 0 {tests => rmp/tests}/func/decode/ext.rs | 0 {tests => rmp/tests}/func/decode/float.rs | 0 {tests => rmp/tests}/func/decode/int.rs | 0 {tests => rmp/tests}/func/decode/map.rs | 0 {tests => rmp/tests}/func/decode/mod.rs | 0 {tests => rmp/tests}/func/decode/null.rs | 0 {tests => rmp/tests}/func/decode/string.rs | 0 {tests => rmp/tests}/func/decode/value.rs | 0 {tests => rmp/tests}/func/decode/value_ref.rs | 0 {tests => rmp/tests}/func/encode/array.rs | 0 {tests => rmp/tests}/func/encode/bin.rs | 0 {tests => rmp/tests}/func/encode/bool.rs | 0 {tests => rmp/tests}/func/encode/ext.rs | 0 {tests => rmp/tests}/func/encode/float.rs | 0 {tests => rmp/tests}/func/encode/int.rs | 0 {tests => rmp/tests}/func/encode/map.rs | 0 {tests => rmp/tests}/func/encode/mod.rs | 0 {tests => rmp/tests}/func/encode/null.rs | 0 {tests => rmp/tests}/func/encode/serializer.rs | 0 {tests => rmp/tests}/func/encode/string.rs | 0 {tests => rmp/tests}/func/encode/value.rs | 0 {tests => rmp/tests}/func/encode/value_ref.rs | 0 {tests => rmp/tests}/func/mod.rs | 0 {tests => rmp/tests}/func/serde.rs | 0 {tests => rmp/tests}/lib.rs | 0 39 files changed, 4 insertions(+), 11 deletions(-) rename Cargo.toml => rmp/Cargo.toml (93%) rename {benches => rmp/benches}/bench.rs (100%) rename {src => rmp/src}/decode.rs (100%) rename {src => rmp/src}/decode/value_ref.rs (100%) rename {src => rmp/src}/encode.rs (100%) rename {src => rmp/src}/encode/value_ref.rs (100%) rename {src => rmp/src}/init.rs (100%) rename {src => rmp/src}/lib.rs (100%) rename {src => rmp/src}/value.rs (100%) rename {tests => rmp/tests}/func/decode/array.rs (100%) rename {tests => rmp/tests}/func/decode/bin.rs (100%) rename {tests => rmp/tests}/func/decode/bool.rs (100%) rename {tests => rmp/tests}/func/decode/deserializer.rs (100%) rename {tests => rmp/tests}/func/decode/ext.rs (100%) rename {tests => rmp/tests}/func/decode/float.rs (100%) rename {tests => rmp/tests}/func/decode/int.rs (100%) rename {tests => rmp/tests}/func/decode/map.rs (100%) rename {tests => rmp/tests}/func/decode/mod.rs (100%) rename {tests => rmp/tests}/func/decode/null.rs (100%) rename {tests => rmp/tests}/func/decode/string.rs (100%) rename {tests => rmp/tests}/func/decode/value.rs (100%) rename {tests => rmp/tests}/func/decode/value_ref.rs (100%) rename {tests => rmp/tests}/func/encode/array.rs (100%) rename {tests => rmp/tests}/func/encode/bin.rs (100%) rename {tests => rmp/tests}/func/encode/bool.rs (100%) rename {tests => rmp/tests}/func/encode/ext.rs (100%) rename {tests => rmp/tests}/func/encode/float.rs (100%) rename {tests => rmp/tests}/func/encode/int.rs (100%) rename {tests => rmp/tests}/func/encode/map.rs (100%) rename {tests => rmp/tests}/func/encode/mod.rs (100%) rename {tests => rmp/tests}/func/encode/null.rs (100%) rename {tests => rmp/tests}/func/encode/serializer.rs (100%) rename {tests => rmp/tests}/func/encode/string.rs (100%) rename {tests => rmp/tests}/func/encode/value.rs (100%) rename {tests => rmp/tests}/func/encode/value_ref.rs (100%) rename {tests => rmp/tests}/func/mod.rs (100%) rename {tests => rmp/tests}/func/serde.rs (100%) rename {tests => rmp/tests}/lib.rs (100%) diff --git a/rmp-serialize/Cargo.toml b/rmp-serialize/Cargo.toml index f0cc4bc4..05b15bbd 100644 --- a/rmp-serialize/Cargo.toml +++ b/rmp-serialize/Cargo.toml @@ -10,5 +10,5 @@ readme = "../README.md" keywords = ["msgpack", "MessagePack", "serialization"] [dependencies] -rmp = { version = "*", path = ".." } +rmp = { version = "*", path = "../rmp" } rustc-serialize = "0.3" diff --git a/Cargo.toml b/rmp/Cargo.toml similarity index 93% rename from Cargo.toml rename to rmp/Cargo.toml index 170094d3..a0dfef28 100644 --- a/Cargo.toml +++ b/rmp/Cargo.toml @@ -1,21 +1,14 @@ [package] - name = "rmp" version = "0.6.0" authors = ["Evgeny Safronov "] - +license = "MIT" description = "Pure Rust MessagePack serialization implementation" - -documentation = "https://3hren.github.io/msgpack-rust/rmp/index.html" - repository = "https://github.com/3Hren/msgpack-rust" - -readme = "README.md" - +documentation = "https://3hren.github.io/msgpack-rust/rmp/index.html" +readme = "../README.md" keywords = ["msgpack", "MessagePack"] -license = "MIT" - [dependencies] byteorder = "*" serde = "*" diff --git a/benches/bench.rs b/rmp/benches/bench.rs similarity index 100% rename from benches/bench.rs rename to rmp/benches/bench.rs diff --git a/src/decode.rs b/rmp/src/decode.rs similarity index 100% rename from src/decode.rs rename to rmp/src/decode.rs diff --git a/src/decode/value_ref.rs b/rmp/src/decode/value_ref.rs similarity index 100% rename from src/decode/value_ref.rs rename to rmp/src/decode/value_ref.rs diff --git a/src/encode.rs b/rmp/src/encode.rs similarity index 100% rename from src/encode.rs rename to rmp/src/encode.rs diff --git a/src/encode/value_ref.rs b/rmp/src/encode/value_ref.rs similarity index 100% rename from src/encode/value_ref.rs rename to rmp/src/encode/value_ref.rs diff --git a/src/init.rs b/rmp/src/init.rs similarity index 100% rename from src/init.rs rename to rmp/src/init.rs diff --git a/src/lib.rs b/rmp/src/lib.rs similarity index 100% rename from src/lib.rs rename to rmp/src/lib.rs diff --git a/src/value.rs b/rmp/src/value.rs similarity index 100% rename from src/value.rs rename to rmp/src/value.rs diff --git a/tests/func/decode/array.rs b/rmp/tests/func/decode/array.rs similarity index 100% rename from tests/func/decode/array.rs rename to rmp/tests/func/decode/array.rs diff --git a/tests/func/decode/bin.rs b/rmp/tests/func/decode/bin.rs similarity index 100% rename from tests/func/decode/bin.rs rename to rmp/tests/func/decode/bin.rs diff --git a/tests/func/decode/bool.rs b/rmp/tests/func/decode/bool.rs similarity index 100% rename from tests/func/decode/bool.rs rename to rmp/tests/func/decode/bool.rs diff --git a/tests/func/decode/deserializer.rs b/rmp/tests/func/decode/deserializer.rs similarity index 100% rename from tests/func/decode/deserializer.rs rename to rmp/tests/func/decode/deserializer.rs diff --git a/tests/func/decode/ext.rs b/rmp/tests/func/decode/ext.rs similarity index 100% rename from tests/func/decode/ext.rs rename to rmp/tests/func/decode/ext.rs diff --git a/tests/func/decode/float.rs b/rmp/tests/func/decode/float.rs similarity index 100% rename from tests/func/decode/float.rs rename to rmp/tests/func/decode/float.rs diff --git a/tests/func/decode/int.rs b/rmp/tests/func/decode/int.rs similarity index 100% rename from tests/func/decode/int.rs rename to rmp/tests/func/decode/int.rs diff --git a/tests/func/decode/map.rs b/rmp/tests/func/decode/map.rs similarity index 100% rename from tests/func/decode/map.rs rename to rmp/tests/func/decode/map.rs diff --git a/tests/func/decode/mod.rs b/rmp/tests/func/decode/mod.rs similarity index 100% rename from tests/func/decode/mod.rs rename to rmp/tests/func/decode/mod.rs diff --git a/tests/func/decode/null.rs b/rmp/tests/func/decode/null.rs similarity index 100% rename from tests/func/decode/null.rs rename to rmp/tests/func/decode/null.rs diff --git a/tests/func/decode/string.rs b/rmp/tests/func/decode/string.rs similarity index 100% rename from tests/func/decode/string.rs rename to rmp/tests/func/decode/string.rs diff --git a/tests/func/decode/value.rs b/rmp/tests/func/decode/value.rs similarity index 100% rename from tests/func/decode/value.rs rename to rmp/tests/func/decode/value.rs diff --git a/tests/func/decode/value_ref.rs b/rmp/tests/func/decode/value_ref.rs similarity index 100% rename from tests/func/decode/value_ref.rs rename to rmp/tests/func/decode/value_ref.rs diff --git a/tests/func/encode/array.rs b/rmp/tests/func/encode/array.rs similarity index 100% rename from tests/func/encode/array.rs rename to rmp/tests/func/encode/array.rs diff --git a/tests/func/encode/bin.rs b/rmp/tests/func/encode/bin.rs similarity index 100% rename from tests/func/encode/bin.rs rename to rmp/tests/func/encode/bin.rs diff --git a/tests/func/encode/bool.rs b/rmp/tests/func/encode/bool.rs similarity index 100% rename from tests/func/encode/bool.rs rename to rmp/tests/func/encode/bool.rs diff --git a/tests/func/encode/ext.rs b/rmp/tests/func/encode/ext.rs similarity index 100% rename from tests/func/encode/ext.rs rename to rmp/tests/func/encode/ext.rs diff --git a/tests/func/encode/float.rs b/rmp/tests/func/encode/float.rs similarity index 100% rename from tests/func/encode/float.rs rename to rmp/tests/func/encode/float.rs diff --git a/tests/func/encode/int.rs b/rmp/tests/func/encode/int.rs similarity index 100% rename from tests/func/encode/int.rs rename to rmp/tests/func/encode/int.rs diff --git a/tests/func/encode/map.rs b/rmp/tests/func/encode/map.rs similarity index 100% rename from tests/func/encode/map.rs rename to rmp/tests/func/encode/map.rs diff --git a/tests/func/encode/mod.rs b/rmp/tests/func/encode/mod.rs similarity index 100% rename from tests/func/encode/mod.rs rename to rmp/tests/func/encode/mod.rs diff --git a/tests/func/encode/null.rs b/rmp/tests/func/encode/null.rs similarity index 100% rename from tests/func/encode/null.rs rename to rmp/tests/func/encode/null.rs diff --git a/tests/func/encode/serializer.rs b/rmp/tests/func/encode/serializer.rs similarity index 100% rename from tests/func/encode/serializer.rs rename to rmp/tests/func/encode/serializer.rs diff --git a/tests/func/encode/string.rs b/rmp/tests/func/encode/string.rs similarity index 100% rename from tests/func/encode/string.rs rename to rmp/tests/func/encode/string.rs diff --git a/tests/func/encode/value.rs b/rmp/tests/func/encode/value.rs similarity index 100% rename from tests/func/encode/value.rs rename to rmp/tests/func/encode/value.rs diff --git a/tests/func/encode/value_ref.rs b/rmp/tests/func/encode/value_ref.rs similarity index 100% rename from tests/func/encode/value_ref.rs rename to rmp/tests/func/encode/value_ref.rs diff --git a/tests/func/mod.rs b/rmp/tests/func/mod.rs similarity index 100% rename from tests/func/mod.rs rename to rmp/tests/func/mod.rs diff --git a/tests/func/serde.rs b/rmp/tests/func/serde.rs similarity index 100% rename from tests/func/serde.rs rename to rmp/tests/func/serde.rs diff --git a/tests/lib.rs b/rmp/tests/lib.rs similarity index 100% rename from tests/lib.rs rename to rmp/tests/lib.rs From 66a14173c3e44f65b9ff18c0d5b19a25baac9e75 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 00:17:03 +0300 Subject: [PATCH 06/12] CI: fix Travis. --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 06f34e55..8b37bd1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,17 @@ rust: - beta - nightly +env: + - CRATE=rmp + - CRATE=rmp-serialize + # Load travis-cargo. before_script: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH +script: +- (cd $CRATE && cargo test) + # Measure code coverage and upload to coveralls.io. after_success: - travis-cargo coveralls --no-sudo From b6e6f44b257de025aac15a603c4391b3b2c21d31 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 00:17:13 +0300 Subject: [PATCH 07/12] Changelog: update. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7ddfd8..0b7bbab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][unreleased] +### Changed +- The big single crate has been refactored, which results in three crates: `rmp`, `rmp-serialize` and `rmp-serde`. ## 0.6.0 - 2015-08-17 ### Added From 7e7e1cee395af751e7e1144a6aef0131ec744e25 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 00:22:28 +0300 Subject: [PATCH 08/12] CI: attempt to fix coveralls. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8b37bd1f..bdbc6529 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ before_script: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: -- (cd $CRATE && cargo test) + - (cd $CRATE && cargo test) # Measure code coverage and upload to coveralls.io. after_success: - - travis-cargo coveralls --no-sudo + - cd $CRATE && travis-cargo coveralls --no-sudo From 3c4f75ba24588c402cfd564ac8903d994253b4ad Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 00:47:27 +0300 Subject: [PATCH 09/12] CI: minor style. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bdbc6529..194b6365 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - - (cd $CRATE && cargo test) + - cd $CRATE && cargo test # Measure code coverage and upload to coveralls.io. after_success: From 769a947c9f5a7561c22dba8a35ce5500a6a08388 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 12:32:20 +0300 Subject: [PATCH 10/12] API: Serde bindings are now in separate crate. --- .travis.yml | 1 + rmp-serde/Cargo.toml | 15 + rmp-serde/src/decode.rs | 387 +++++++++++++ rmp-serde/src/encode.rs | 296 ++++++++++ rmp-serde/src/lib.rs | 8 + rmp-serde/tests/deserializer.rs | 479 ++++++++++++++++ {rmp/tests/func => rmp-serde/tests}/serde.rs | 5 +- .../encode => rmp-serde/tests}/serializer.rs | 10 +- rmp/Cargo.toml | 2 - rmp/src/decode.rs | 403 +------------- rmp/src/encode.rs | 306 +---------- rmp/src/lib.rs | 5 - rmp/tests/func/decode/deserializer.rs | 516 ------------------ rmp/tests/func/decode/mod.rs | 1 - rmp/tests/func/encode/mod.rs | 1 - rmp/tests/func/mod.rs | 1 - rmp/tests/lib.rs | 4 - 17 files changed, 1206 insertions(+), 1234 deletions(-) create mode 100644 rmp-serde/Cargo.toml create mode 100644 rmp-serde/src/decode.rs create mode 100644 rmp-serde/src/encode.rs create mode 100644 rmp-serde/src/lib.rs create mode 100644 rmp-serde/tests/deserializer.rs rename {rmp/tests/func => rmp-serde/tests}/serde.rs (92%) rename {rmp/tests/func/encode => rmp-serde/tests}/serializer.rs (97%) delete mode 100644 rmp/tests/func/decode/deserializer.rs diff --git a/.travis.yml b/.travis.yml index 194b6365..80e3cbb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ rust: env: - CRATE=rmp - CRATE=rmp-serialize + - CRATE=rmp-serde # Load travis-cargo. before_script: diff --git a/rmp-serde/Cargo.toml b/rmp-serde/Cargo.toml new file mode 100644 index 00000000..d3dffbe4 --- /dev/null +++ b/rmp-serde/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rmp-serde" +version = "0.6.0" +authors = ["Evgeny Safronov "] +license = "MIT" +description = "Serde bindings for RMP" +repository = "https://github.com/3Hren/msgpack-rust" +documentation = "https://3hren.github.io/msgpack-rust/rmp/index.html" +readme = "../README.md" +keywords = ["msgpack", "MessagePack", "serder", "serialization"] + +[dependencies] +rmp = { version = "*", path = "../rmp" } +serde = "*" +serde_macros = { version = "*", optional = true } diff --git a/rmp-serde/src/decode.rs b/rmp-serde/src/decode.rs new file mode 100644 index 00000000..b7359a05 --- /dev/null +++ b/rmp-serde/src/decode.rs @@ -0,0 +1,387 @@ +use std::convert::From; +use std::fmt; +use std::io::Read; +use std::result; + +use serde; + +use rmp::Marker; +use rmp::decode::{ + DecodeStringError, + FixedValueReadError, + MarkerReadError, + ReadError, + ValueReadError, + read_numeric_data, + read_str_data, + read_marker, + read_full, +}; + +/// Unstable: docs; incomplete +#[derive(Debug)] +pub enum Error { + /// The actual value type isn't equal with the expected one. + TypeMismatch(Marker), + InvalidMarkerRead(ReadError), + InvalidDataRead(ReadError), + LengthMismatch(u32), + /// Uncategorized error. + Uncategorized(String), + Syntax(String), +} + +impl ::std::error::Error for Error { + fn description(&self) -> &str { "error while decoding value" } + + fn cause(&self) -> Option<&::std::error::Error> { + use self::Error::*; + match *self { + TypeMismatch(_) => None, + InvalidMarkerRead(ref err) => Some(err), + InvalidDataRead(ref err) => Some(err), + LengthMismatch(_) => None, + Uncategorized(_) => None, + Syntax(_) => None, + } + } +} + +impl serde::de::Error for Error { + fn syntax(msg: &str) -> Error { + Error::Syntax(format!("syntax error: {}", msg)) + } + + fn length_mismatch(len: usize) -> Error { + Error::LengthMismatch(len as u32) + } + + fn type_mismatch(ty: serde::de::Type) -> Error { + match ty { + serde::de::Type::Bool => Error::TypeMismatch(Marker::True), + serde::de::Type::Usize => Error::TypeMismatch(Marker::FixPos(0)), + serde::de::Type::U8 => Error::TypeMismatch(Marker::U8), + serde::de::Type::U16 => Error::TypeMismatch(Marker::U16), + serde::de::Type::U32 => Error::TypeMismatch(Marker::U32), + serde::de::Type::U64 => Error::TypeMismatch(Marker::U64), + serde::de::Type::Isize => Error::TypeMismatch(Marker::FixNeg(0)), + serde::de::Type::I8 => Error::TypeMismatch(Marker::I8), + serde::de::Type::I16 => Error::TypeMismatch(Marker::I16), + serde::de::Type::I32 => Error::TypeMismatch(Marker::I32), + serde::de::Type::I64 => Error::TypeMismatch(Marker::I64), + serde::de::Type::F32 => Error::TypeMismatch(Marker::F32), + serde::de::Type::F64 => Error::TypeMismatch(Marker::F64), + serde::de::Type::Char => Error::TypeMismatch(Marker::Str32), + serde::de::Type::Str => Error::TypeMismatch(Marker::Str32), + serde::de::Type::String => Error::TypeMismatch(Marker::Str32), + serde::de::Type::Unit => Error::TypeMismatch(Marker::Null), + serde::de::Type::Option => Error::TypeMismatch(Marker::True), + serde::de::Type::Seq => Error::TypeMismatch(Marker::Array32), + serde::de::Type::Map => Error::TypeMismatch(Marker::Map32), + serde::de::Type::UnitStruct => Error::TypeMismatch(Marker::Null), + serde::de::Type::NewtypeStruct => Error::TypeMismatch(Marker::Array32), + serde::de::Type::TupleStruct => Error::TypeMismatch(Marker::Array32), + serde::de::Type::Struct => Error::TypeMismatch(Marker::Map32), + serde::de::Type::Tuple => Error::TypeMismatch(Marker::Array32), + serde::de::Type::Enum => Error::TypeMismatch(Marker::Array32), + serde::de::Type::StructVariant => Error::TypeMismatch(Marker::Map32), + serde::de::Type::TupleVariant => Error::TypeMismatch(Marker::Array32), + serde::de::Type::UnitVariant => Error::TypeMismatch(Marker::Array32), + serde::de::Type::Bytes => Error::TypeMismatch(Marker::Array32), + } + } + + fn end_of_stream() -> Error { + Error::Uncategorized("end of stream".to_string()) + } + + fn missing_field(_field: &str) -> Error { + Error::Uncategorized("missing field".to_string()) + } + + fn unknown_field(_field: &str) -> Error { + Error::Uncategorized("unknown field".to_string()) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::std::error::Error::description(self).fmt(f) + } +} + +impl From for Error { + fn from(err: FixedValueReadError) -> Error { + match err { + FixedValueReadError::UnexpectedEOF => Error::InvalidMarkerRead(ReadError::UnexpectedEOF), + FixedValueReadError::Io(err) => Error::InvalidMarkerRead(ReadError::Io(err)), + FixedValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + } + } +} + +impl From for Error { + fn from(err: ValueReadError) -> Error { + match err { + ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), + ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), + } + } +} + +/// Unstable: docs; incomplete +impl<'a> From> for Error { + fn from(err: DecodeStringError) -> Error { + match err { + DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), + DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()), + DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()), + DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()), + DecodeStringError::InvalidDataCopy(..) => Error::Uncategorized("InvalidDataCopy".to_string()), + DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()), + } + } +} + +impl From for Error { + fn from(err: MarkerReadError) -> Error { + Error::InvalidMarkerRead(From::from(err)) + } +} + +pub type Result = result::Result; + +/// # Note +/// +/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying +/// operation is retried. +// TODO: Docs. Examples. +pub struct Deserializer { + rd: R, + buf: Vec, +} + +impl Deserializer { + // TODO: Docs. + pub fn new(rd: R) -> Deserializer { + Deserializer { + rd: rd, + buf: Vec::new(), + } + } + + /// Gets a reference to the underlying reader in this decoder. + pub fn get_ref(&self) -> &R { + &self.rd + } + + /// Gets a mutable reference to the underlying reader in this decoder. + pub fn get_mut(&mut self) -> &mut R { + &mut self.rd + } + + /// Consumes this decoder returning the underlying reader. + pub fn into_inner(self) -> R { + self.rd + } + + fn read_str(&mut self, len: u32, mut visitor: V) -> Result + where V: serde::de::Visitor + { + self.buf.clear(); + self.buf.extend((0..len).map(|_| 0)); + visitor.visit_str(try!(read_str_data(&mut self.rd, len, &mut self.buf[..]))) + } + + fn read_array(&mut self, len: u32, mut visitor: V) -> Result + where V: serde::de::Visitor + { + visitor.visit_seq(SeqVisitor { + deserializer: self, + len: len, + actual: len, + }) + } + + fn read_map(&mut self, len: u32, mut visitor: V) -> Result + where V: serde::de::Visitor + { + visitor.visit_map(MapVisitor { + deserializer: self, + len: len, + actual: len, + }) + } + + fn read_bin_data(&mut self, len: usize, mut visitor: V) -> Result + where V: serde::de::Visitor + { + self.buf.clear(); + self.buf.extend((0..len).map(|_| 0)); + + match read_full(&mut self.rd, &mut self.buf[..]) { + Ok(n) if n == self.buf.len() => (), + Ok(..) => return Err(Error::InvalidDataRead(ReadError::UnexpectedEOF)), + Err(err) => return Err(Error::InvalidDataRead(ReadError::Io(err))), + } + + visitor.visit_bytes(&mut self.buf[..]) + } +} + +/// Unstable: docs; examples; incomplete +impl serde::Deserializer for Deserializer { + type Error = Error; + + fn visit(&mut self, mut visitor: V) -> Result + where V: serde::de::Visitor + { + match try!(read_marker(&mut self.rd)) { + Marker::Null => visitor.visit_unit(), + Marker::True => visitor.visit_bool(true), + Marker::False => visitor.visit_bool(false), + Marker::FixPos(val) => visitor.visit_u8(val), + Marker::FixNeg(val) => visitor.visit_i8(val), + Marker::U8 => visitor.visit_u8(try!(read_numeric_data(&mut self.rd))), + Marker::U16 => visitor.visit_u16(try!(read_numeric_data(&mut self.rd))), + Marker::U32 => visitor.visit_u32(try!(read_numeric_data(&mut self.rd))), + Marker::U64 => visitor.visit_u64(try!(read_numeric_data(&mut self.rd))), + Marker::I8 => visitor.visit_i8(try!(read_numeric_data(&mut self.rd))), + Marker::I16 => visitor.visit_i16(try!(read_numeric_data(&mut self.rd))), + Marker::I32 => visitor.visit_i32(try!(read_numeric_data(&mut self.rd))), + Marker::I64 => visitor.visit_i64(try!(read_numeric_data(&mut self.rd))), + Marker::F32 => visitor.visit_f32(try!(read_numeric_data(&mut self.rd))), + Marker::F64 => visitor.visit_f64(try!(read_numeric_data(&mut self.rd))), + Marker::FixStr(len) => self.read_str(len as u32, visitor), + Marker::Str8 => { + let len: u8 = try!(read_numeric_data(&mut self.rd)); + self.read_str(len as u32, visitor) + } + Marker::Str16 => { + let len: u16 = try!(read_numeric_data(&mut self.rd)); + self.read_str(len as u32, visitor) + } + Marker::Str32 => { + let len: u32 = try!(read_numeric_data(&mut self.rd)); + self.read_str(len, visitor) + } + Marker::FixArray(len) => { + self.read_array(len as u32, visitor) + } + Marker::Array16 => { + let len: u16 = try!(read_numeric_data(&mut self.rd)); + self.read_array(len as u32, visitor) + } + Marker::Array32 => { + let len: u32 = try!(read_numeric_data(&mut self.rd)); + self.read_array(len, visitor) + } + Marker::FixMap(len) => { + self.read_map(len as u32, visitor) + } + Marker::Map16 => { + let len: u16 = try!(read_numeric_data(&mut self.rd)); + self.read_map(len as u32, visitor) + } + Marker::Map32 => { + let len: u32 = try!(read_numeric_data(&mut self.rd)); + self.read_map(len, visitor) + } + Marker::Bin8 => { + let len: u8 = try!(read_numeric_data(&mut self.rd)); + self.read_bin_data(len as usize, visitor) + } + Marker::Bin16 => { + let len: u16 = try!(read_numeric_data(&mut self.rd)); + self.read_bin_data(len as usize, visitor) + } + Marker::Bin32 => { + let len: u32 = try!(read_numeric_data(&mut self.rd)); + self.read_bin_data(len as usize, visitor) + } + Marker::Reserved => Err(Error::TypeMismatch(Marker::Reserved)), + // TODO: Make something with exts. + marker => Err(From::from(FixedValueReadError::TypeMismatch(marker))), + } + } + + /// We treat Value::Null as None. + fn visit_option(&mut self, mut visitor: V) -> Result + where V: serde::de::Visitor, + { + // Primarily try to read optimisticly. + match visitor.visit_some(self) { + Ok(val) => Ok(val), + Err(Error::TypeMismatch(Marker::Null)) => visitor.visit_none(), + Err(err) => Err(err) + } + } +} + +struct SeqVisitor<'a, R: Read + 'a> { + deserializer: &'a mut Deserializer, + len: u32, + actual: u32, +} + +impl<'a, R: Read + 'a> serde::de::SeqVisitor for SeqVisitor<'a, R> { + type Error = Error; + + fn visit(&mut self) -> Result> + where T: serde::de::Deserialize, + { + if self.len > 0 { + self.len -= 1; + let value = try!(serde::Deserialize::deserialize(self.deserializer)); + Ok(Some(value)) + } else { + Ok(None) + } + } + + fn end(&mut self) -> Result<()> { + if self.len == 0 { + Ok(()) + } else { + Err(Error::LengthMismatch(self.actual)) + } + } +} + +struct MapVisitor<'a, R: Read + 'a> { + deserializer: &'a mut Deserializer, + len: u32, + actual: u32, +} + +impl<'a, R: Read + 'a> serde::de::MapVisitor for MapVisitor<'a, R> { + type Error = Error; + + fn visit_key(&mut self) -> Result> + where K: serde::de::Deserialize, + { + if self.len > 0 { + self.len -= 1; + let key = try!(serde::Deserialize::deserialize(self.deserializer)); + Ok(Some(key)) + } else { + Ok(None) + } + } + + fn visit_value(&mut self) -> Result + where V: serde::de::Deserialize, + { + let value = try!(serde::Deserialize::deserialize(self.deserializer)); + Ok(value) + } + + fn end(&mut self) -> Result<()> { + if self.len == 0 { + Ok(()) + } else { + Err(Error::LengthMismatch(self.actual)) + } + } +} diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs new file mode 100644 index 00000000..1f49cf0d --- /dev/null +++ b/rmp-serde/src/encode.rs @@ -0,0 +1,296 @@ +use serde; + +use std::fmt; +use std::io::Write; + +use rmp::encode::{ + write_nil, + write_bool, + write_uint, + write_sint, + write_f32, + write_f64, + write_str, + write_array_len, + write_map_len, + write_bin_len, + WriteError, + FixedValueWriteError, + ValueWriteError, +}; + +#[derive(Debug)] +pub enum Error { + /// Failed to write MessagePack'ed single-byte value into the write. + InvalidFixedValueWrite(WriteError), + InvalidValueWrite(ValueWriteError), +} + +impl ::std::error::Error for Error { + fn description(&self) -> &str { "an error occurred while writing encoded value" } + + fn cause(&self) -> Option<&::std::error::Error> { + match *self { + Error::InvalidFixedValueWrite(ref err) => Some(err), + Error::InvalidValueWrite(ref err) => Some(err), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::std::error::Error::description(self).fmt(f) + } +} + + +impl From for Error { + fn from(err: FixedValueWriteError) -> Error { + match err { + FixedValueWriteError(err) => Error::InvalidFixedValueWrite(err) + } + } +} + +impl From for Error { + fn from(err: ValueWriteError) -> Error { + Error::InvalidValueWrite(err) + } +} + +/// Represents MessagePack serialization implementation. +/// +/// # Note +/// +/// MessagePack has no specification about how to encode variant types. Thus we are free to do +/// whatever we want, so the given chose may be not ideal for you. +/// +/// Every Rust variant value can be represented as a tuple of index and a value. +/// +/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying +/// operation is retried. +// TODO: Docs. Examples. +pub struct Serializer<'a> { + wr: &'a mut Write, +} + +impl<'a> Serializer<'a> { + /// Creates a new MessagePack encoder whose output will be written to the writer specified. + pub fn new(wr: &'a mut Write) -> Serializer<'a> { + Serializer { + wr: wr, + } + } +} + +impl<'a> serde::Serializer for Serializer<'a> { + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + write_nil(&mut self.wr).map_err(From::from) + } + + fn visit_bool(&mut self, val: bool) -> Result<(), Error> { + write_bool(&mut self.wr, val).map_err(From::from) + } + + fn visit_u8(&mut self, val: u8) -> Result<(), Error> { + self.visit_u64(val as u64) + } + + fn visit_u16(&mut self, val: u16) -> Result<(), Error> { + self.visit_u64(val as u64) + } + + fn visit_u32(&mut self, val: u32) -> Result<(), Error> { + self.visit_u64(val as u64) + } + + fn visit_u64(&mut self, val: u64) -> Result<(), Error> { + try!(write_uint(&mut self.wr, val)); + + Ok(()) + } + + fn visit_usize(&mut self, val: usize) -> Result<(), Error> { + self.visit_u64(val as u64) + } + + fn visit_i8(&mut self, val: i8) -> Result<(), Error> { + self.visit_i64(val as i64) + } + + fn visit_i16(&mut self, val: i16) -> Result<(), Error> { + self.visit_i64(val as i64) + } + + fn visit_i32(&mut self, val: i32) -> Result<(), Error> { + self.visit_i64(val as i64) + } + + fn visit_i64(&mut self, val: i64) -> Result<(), Error> { + try!(write_sint(&mut self.wr, val)); + + Ok(()) + } + + fn visit_isize(&mut self, val: isize) -> Result<(), Error> { + self.visit_i64(val as i64) + } + + fn visit_f32(&mut self, val: f32) -> Result<(), Error> { + write_f32(&mut self.wr, val).map_err(From::from) + } + + fn visit_f64(&mut self, val: f64) -> Result<(), Error> { + write_f64(&mut self.wr, val).map_err(From::from) + } + + // TODO: The implementation involves heap allocation and is unstable. + fn visit_char(&mut self, val: char) -> Result<(), Error> { + let mut buf = String::new(); + buf.push(val); + self.visit_str(&buf) + } + + fn visit_str(&mut self, val: &str) -> Result<(), Error> { + write_str(&mut self.wr, val).map_err(From::from) + } + + fn visit_unit_variant(&mut self, + _name: &str, + variant_index: usize, + _variant: &str) -> Result<(), Error> + { + // Mark that we want to encode a variant type. + try!(write_array_len(&mut self.wr, 2)); + + // Encode a value position... + try!(self.visit_usize(variant_index)); + + // ... and its arguments length. + try!(write_array_len(&mut self.wr, 0)); + + Ok(()) + } + + /// Encodes and attempts to write the enum value into the Write. + /// + /// Currently we encode variant types as a tuple of id with array of args, like: [id, [args...]] + fn visit_tuple_variant(&mut self, + _name: &str, + variant_index: usize, + _variant: &str, + mut visitor: V) -> Result<(), Error> + where V: serde::ser::SeqVisitor, + { + // Mark that we want to encode a variant type. + try!(write_array_len(&mut self.wr, 2)); + + // Encode a value position... + try!(self.visit_usize(variant_index)); + + let len = match visitor.len() { + Some(len) => len, + None => panic!("do not know how to serialize a sequence with no length"), + }; + + // ... and its arguments length. + try!(write_array_len(&mut self.wr, len as u32)); + + while let Some(()) = try!(visitor.visit(self)) { } + + Ok(()) + } + + fn visit_struct_variant(&mut self, + _name: &str, + _variant_index: usize, + _variant: &str, + _visitor: V) -> Result<(), Error> + where V: serde::ser::MapVisitor, + { + unimplemented!() + } + + fn visit_none(&mut self) -> Result<(), Error> { + self.visit_unit() + } + + fn visit_some(&mut self, v: T) -> Result<(), Error> + where T: serde::Serialize, + { + v.serialize(self) + } + + // TODO: Check len, overflow is possible. + fn visit_seq(&mut self, mut visitor: V) -> Result<(), Error> + 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!(write_array_len(&mut self.wr, len as u32)); + + while let Some(()) = try!(visitor.visit(self)) { } + + Ok(()) + } + + fn visit_seq_elt(&mut self, value: V) -> Result<(), Error> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn visit_map(&mut self, mut visitor: V) -> Result<(), Error> + 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!(write_map_len(&mut self.wr, len as u32)); + + while let Some(()) = try!(visitor.visit(self)) { } + + Ok(()) + } + + fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Error> + where K: serde::Serialize, + V: serde::Serialize, + { + try!(key.serialize(self)); + value.serialize(self) + } + + fn visit_struct(&mut self, _name: &str, mut visitor: V) -> Result<(), Error> + where V: serde::ser::MapVisitor, + { + let len = match visitor.len() { + Some(len) => len, + None => panic!("do not know how to serialize a sequence with no length"), + }; + + try!(write_array_len(&mut self.wr, len as u32)); + + while let Some(()) = try!(visitor.visit(self)) { } + + Ok(()) + } + + fn visit_struct_elt(&mut self, _key: &str, value: V) -> Result<(), Error> + where V: serde::Serialize, + { + value.serialize(self) + } + + fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Error> { + try!(write_bin_len(&mut self.wr, value.len() as u32)); + self.wr.write_all(value).map_err(|err| Error::InvalidValueWrite(ValueWriteError::InvalidDataWrite(WriteError(err)))) + } +} diff --git a/rmp-serde/src/lib.rs b/rmp-serde/src/lib.rs new file mode 100644 index 00000000..a30ef374 --- /dev/null +++ b/rmp-serde/src/lib.rs @@ -0,0 +1,8 @@ +extern crate rmp; +extern crate serde; + +pub mod decode; +pub mod encode; + +pub use decode::Deserializer; +pub use encode::Serializer; diff --git a/rmp-serde/tests/deserializer.rs b/rmp-serde/tests/deserializer.rs new file mode 100644 index 00000000..be880716 --- /dev/null +++ b/rmp-serde/tests/deserializer.rs @@ -0,0 +1,479 @@ +#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))] +#![cfg_attr(feature = "serde_macros", plugin(serde_macros))] + +extern crate serde; +extern crate rmp; +extern crate rmp_serde; + +use std::io::Cursor; +use std::result; + +use serde::Deserialize; + +use rmp::Marker; +use rmp_serde::Deserializer; +use rmp_serde::decode::Error; + +type Result = result::Result; + +#[test] +fn pass_null() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!((), Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn fail_null_from_reserved() { + let buf = [0xc1]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + let res: Result<()> = Deserialize::deserialize(&mut deserializer); + match res.err() { + Some(Error::TypeMismatch(Marker::Reserved)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_bool() { + let buf = [0xc2, 0xc3]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(false, Deserialize::deserialize(&mut deserializer).ok().unwrap()); + assert_eq!(true, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn fail_bool_from_fixint() { + let buf = [0x00]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + let res: Result = Deserialize::deserialize(&mut deserializer); + match res.err() { + Some(Error::TypeMismatch(Marker::U64)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_u64() { + let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(18446744073709551615u64, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_u32() { + let buf = [0xce, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(4294967295u32, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn fail_u32_from_u64() { + let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + let res: Result = Deserialize::deserialize(&mut deserializer); + match res.err() { + Some(Error::TypeMismatch(Marker::U64)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_u16() { + let buf = [0xcd, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(65535u16, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_u8() { + let buf = [0xcc, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(255u8, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_usize() { + let buf = [0xcc, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(255usize, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_i64() { + let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(9223372036854775807i64, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_i32() { + let buf = [0xd2, 0x7f, 0xff, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(2147483647i32, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_i16() { + let buf = [0xd1, 0x7f, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(32767i16, Deserialize::deserialize(&mut deserializer).ok().unwrap()); +} + +#[test] +fn pass_i8() { + let buf = [0xd0, 0x7f]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(127i8, Deserialize::deserialize(&mut deserializer).unwrap()); +} + +#[test] +fn pass_isize() { + let buf = [0xd0, 0x7f]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(127isize, Deserialize::deserialize(&mut deserializer).unwrap()); +} + +#[test] +fn pass_f32() { + let buf = [0xca, 0x7f, 0x7f, 0xff, 0xff]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(3.4028234e38_f32, Deserialize::deserialize(&mut deserializer).unwrap()); +} + +#[test] +fn pass_f64() { + let buf = [0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + + assert_eq!(42f64, Deserialize::deserialize(&mut deserializer).unwrap()); +} + +#[test] +fn pass_string() { + let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: String = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!("le message".to_string(), actual); +} + +#[test] +fn pass_tuple() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: (u32, u32) = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!((42, 100500), actual); +} + +#[test] +fn fail_tuple_len_mismatch() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Result<(u32,)> = Deserialize::deserialize(&mut deserializer); + + match actual.err() { + Some(Error::LengthMismatch(2)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[cfg(feature = "serde_macros")] +#[test] +fn pass_tuple_struct() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + struct Decoded(u32, u32); + + let mut deserializer = Deserializer::new(cur); + let actual: Decoded = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!(Decoded(42, 100500), actual); +} + +#[cfg(feature = "serde_macros")] +#[test] +fn pass_struct() { + let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + struct Decoded { id: u32, value: u32 }; + + let mut deserializer = Deserializer::new(cur); + let actual: Decoded = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!(Decoded { id: 42, value: 100500 }, actual); +} + +#[test] +fn pass_option_some() { + let buf = [0x1f]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Option = Deserialize::deserialize(&mut deserializer).unwrap(); + assert_eq!(Some(31), actual); +} + +#[test] +fn pass_option_some_null() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Option<()> = Deserialize::deserialize(&mut deserializer).unwrap(); + assert_eq!(Some(()), actual); +} + +#[test] +fn pass_option_none() { + let buf = [0xc0]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Option = Deserialize::deserialize(&mut deserializer).unwrap(); + assert_eq!(None, actual); +} + +#[test] +fn fail_option_u8_from_reserved() { + let buf = [0xc1]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Result> = Deserialize::deserialize(&mut deserializer); + match actual.err() { + Some(Error::TypeMismatch(Marker::Reserved)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[test] +fn pass_vector() { + let buf = [0x92, 0x00, 0xcc, 0x80]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: Vec = Deserialize::deserialize(&mut deserializer).unwrap(); + assert_eq!(vec![0, 128], actual); +} + +#[test] +fn pass_map() { + use std::collections::HashMap; + + let buf = [ + 0x82, // 2 (size) + 0xa3, 0x69, 0x6e, 0x74, // 'int' + 0xcc, 0x80, // 128 + 0xa3, 0x6b, 0x65, 0x79, // 'key' + 0x2a // 42 + ]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: HashMap = Deserialize::deserialize(&mut deserializer).unwrap(); + let mut expected = HashMap::new(); + expected.insert("int".to_string(), 128); + expected.insert("key".to_string(), 42); + + assert_eq!(expected, actual); +} + +#[cfg(feature = "serde_macros")] +#[test] +fn pass_enum() { + let buf = [0x92, 0x01, 0x90]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + enum Custom { + First, + Second, + } + + let mut deserializer = Deserializer::new(cur); + let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!(Custom::Second, actual); +} + +#[cfg(feature = "serde_macros")] +#[test] +fn pass_enum_variant_with_arg() { + let buf = [0x92, 0x01, 0x91, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + enum Custom { + First, + Second(u32), + } + + let mut deserializer = Deserializer::new(cur); + let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!(Custom::Second(42), actual); +} + +#[cfg(feature = "serde_macros")] +#[test] +fn fail_enum_sequence_mismatch() { + let buf = [0x93, 0x1, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + enum Custom { + First, + Second, + } + + let mut deserializer = Deserializer::new(cur); + let actual: Result = Deserialize::deserialize(&mut deserializer); + + match actual.err() { + Some(Error::Uncategorized(..)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[cfg(feature = "serde_macros")] +#[test] +fn fail_enum_overflow() { + let buf = [0x92, 0x01, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + enum Custom { + First, + } + + let mut deserializer = Deserializer::new(cur); + let actual: Result = Deserialize::deserialize(&mut deserializer); + + match actual.err() { + Some(Error::Uncategorized(..)) => (), + other => panic!("unexpected result: {:?}", other) + } +} + +#[cfg(feature = "serde_macros")] +#[test] +fn pass_struct_enum_with_arg() { + let buf = [0x92, 0x01, 0x91, 0x2a]; + let cur = Cursor::new(&buf[..]); + + #[derive(Debug, PartialEq, Deserialize)] + enum Custom { + First, + Second { id: u32 }, + } + + let mut deserializer = Deserializer::new(cur); + let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); + + assert_eq!(Custom::Second { id: 42 }, actual); +} + +// TODO: Merge three of them. +#[test] +fn pass_bin8_into_bytebuf() { + use serde::bytes::ByteBuf; + + let buf = [0xc4, 0x02, 0xcc, 0x80]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); + let actual: Vec = actual.into(); + + assert_eq!(vec![0xcc, 0x80], actual); +} + +#[test] +fn pass_bin16_into_bytebuf() { + use serde::bytes::ByteBuf; + + let buf = [0xc5, 0x00, 0x02, 0xcc, 0x80]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); + let actual: Vec = actual.into(); + + assert_eq!(vec![0xcc, 0x80], actual); +} + +#[test] +fn pass_bin32_into_bytebuf() { + use serde::bytes::ByteBuf; + + let buf = [0xc6, 0x00, 0x00, 0x00, 0x02, 0xcc, 0x80]; + let cur = Cursor::new(&buf[..]); + + let mut deserializer = Deserializer::new(cur); + let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); + let actual: Vec = actual.into(); + + assert_eq!(vec![0xcc, 0x80], actual); +} diff --git a/rmp/tests/func/serde.rs b/rmp-serde/tests/serde.rs similarity index 92% rename from rmp/tests/func/serde.rs rename to rmp-serde/tests/serde.rs index 943fb534..fd532703 100644 --- a/rmp/tests/func/serde.rs +++ b/rmp-serde/tests/serde.rs @@ -1,8 +1,11 @@ +extern crate serde; +extern crate rmp_serde; + use std::io::Cursor; use serde::Deserialize; -use msgpack::Deserializer; +use rmp_serde::Deserializer; #[test] fn pass_deserializer_get_ref() { diff --git a/rmp/tests/func/encode/serializer.rs b/rmp-serde/tests/serializer.rs similarity index 97% rename from rmp/tests/func/encode/serializer.rs rename to rmp-serde/tests/serializer.rs index bbd5fc4d..c20fdfed 100644 --- a/rmp/tests/func/encode/serializer.rs +++ b/rmp-serde/tests/serializer.rs @@ -1,9 +1,15 @@ +#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))] +#![cfg_attr(feature = "serde_macros", plugin(serde_macros))] + +extern crate serde; +extern crate rmp_serde; + use std::io::Cursor; use serde::Serialize; -use msgpack::Serializer; -use msgpack::encode::serde::Error; +use rmp_serde::Serializer; +use rmp_serde::encode::Error; #[test] fn pass_null() { diff --git a/rmp/Cargo.toml b/rmp/Cargo.toml index a0dfef28..25913f9b 100644 --- a/rmp/Cargo.toml +++ b/rmp/Cargo.toml @@ -11,5 +11,3 @@ keywords = ["msgpack", "MessagePack"] [dependencies] byteorder = "*" -serde = "*" -serde_macros = { version = "*", optional = true } diff --git a/rmp/src/decode.rs b/rmp/src/decode.rs index 928437fd..2a676d67 100644 --- a/rmp/src/decode.rs +++ b/rmp/src/decode.rs @@ -264,7 +264,7 @@ impl<'a> From for DecodeStringError<'a> { } /// Attempts to read a single byte from the given reader and decodes it as a MessagePack marker. -fn read_marker(rd: &mut R) -> Result +pub fn read_marker(rd: &mut R) -> Result where R: Read { match rd.read_u8() { @@ -379,7 +379,8 @@ pub fn read_nfix(rd: &mut R) -> Result } } -trait BigEndianRead: Sized { +// TODO Make private again (pub is required for serde crate). +pub trait BigEndianRead: Sized { fn read(rd: &mut R) -> Result; } @@ -443,7 +444,8 @@ impl BigEndianRead for f64 { } } -fn read_numeric_data(rd: &mut R) -> Result +// TODO: Make private (pub is required for serde crate). +pub fn read_numeric_data(rd: &mut R) -> Result where R: Read, D: BigEndianRead { @@ -1353,7 +1355,8 @@ fn read_fixext_data(rd: &mut R, buf: &mut [u8]) -> Result /// This function will return an error immediately if any call to `read` returns an error. All /// instances of `ErrorKind::Interrupted` are handled by this function and the underlying operation /// is retried. -fn read_full(rd: &mut R, buf: &mut [u8]) -> Result { +// TODO Make private again (pub is required for serde crate). +pub fn read_full(rd: &mut R, buf: &mut [u8]) -> Result { // TODO: Maybe move this helper function into an independent module let mut nread = 0usize; @@ -1702,396 +1705,4 @@ pub fn read_value(rd: &mut R) -> Result } // mod value -pub mod serde { - -use std::convert::From; -use std::fmt; -use std::io::Read; -use std::result; - -use serde; - -use super::super::Marker; -use super::{ - ReadError, - FixedValueReadError, - MarkerReadError, - ValueReadError, - DecodeStringError, - read_numeric_data, - read_str_data, - read_marker, - read_full, -}; - -/// Unstable: docs; incomplete -#[derive(Debug)] -pub enum Error { - /// The actual value type isn't equal with the expected one. - TypeMismatch(Marker), - InvalidMarkerRead(ReadError), - InvalidDataRead(ReadError), - LengthMismatch(u32), - /// Uncategorized error. - Uncategorized(String), - Syntax(String), -} - -impl ::std::error::Error for Error { - fn description(&self) -> &str { "error while decoding value" } - - fn cause(&self) -> Option<&::std::error::Error> { - use self::Error::*; - match *self { - TypeMismatch(_) => None, - InvalidMarkerRead(ref err) => Some(err), - InvalidDataRead(ref err) => Some(err), - LengthMismatch(_) => None, - Uncategorized(_) => None, - Syntax(_) => None, - } - } -} - -impl serde::de::Error for Error { - fn syntax(msg: &str) -> Error { - Error::Syntax(format!("syntax error: {}", msg)) - } - - fn length_mismatch(len: usize) -> Error { - Error::LengthMismatch(len as u32) - } - - fn type_mismatch(ty: serde::de::Type) -> Error { - match ty { - serde::de::Type::Bool => Error::TypeMismatch(Marker::True), - serde::de::Type::Usize => Error::TypeMismatch(Marker::FixPos(0)), - serde::de::Type::U8 => Error::TypeMismatch(Marker::U8), - serde::de::Type::U16 => Error::TypeMismatch(Marker::U16), - serde::de::Type::U32 => Error::TypeMismatch(Marker::U32), - serde::de::Type::U64 => Error::TypeMismatch(Marker::U64), - serde::de::Type::Isize => Error::TypeMismatch(Marker::FixNeg(0)), - serde::de::Type::I8 => Error::TypeMismatch(Marker::I8), - serde::de::Type::I16 => Error::TypeMismatch(Marker::I16), - serde::de::Type::I32 => Error::TypeMismatch(Marker::I32), - serde::de::Type::I64 => Error::TypeMismatch(Marker::I64), - serde::de::Type::F32 => Error::TypeMismatch(Marker::F32), - serde::de::Type::F64 => Error::TypeMismatch(Marker::F64), - serde::de::Type::Char => Error::TypeMismatch(Marker::Str32), - serde::de::Type::Str => Error::TypeMismatch(Marker::Str32), - serde::de::Type::String => Error::TypeMismatch(Marker::Str32), - serde::de::Type::Unit => Error::TypeMismatch(Marker::Null), - serde::de::Type::Option => Error::TypeMismatch(Marker::True), - serde::de::Type::Seq => Error::TypeMismatch(Marker::Array32), - serde::de::Type::Map => Error::TypeMismatch(Marker::Map32), - serde::de::Type::UnitStruct => Error::TypeMismatch(Marker::Null), - serde::de::Type::NewtypeStruct => Error::TypeMismatch(Marker::Array32), - serde::de::Type::TupleStruct => Error::TypeMismatch(Marker::Array32), - serde::de::Type::Struct => Error::TypeMismatch(Marker::Map32), - serde::de::Type::Tuple => Error::TypeMismatch(Marker::Array32), - serde::de::Type::Enum => Error::TypeMismatch(Marker::Array32), - serde::de::Type::StructVariant => Error::TypeMismatch(Marker::Map32), - serde::de::Type::TupleVariant => Error::TypeMismatch(Marker::Array32), - serde::de::Type::UnitVariant => Error::TypeMismatch(Marker::Array32), - serde::de::Type::Bytes => Error::TypeMismatch(Marker::Array32), - } - } - - fn end_of_stream() -> Error { - Error::Uncategorized("end of stream".to_string()) - } - - fn missing_field(_field: &str) -> Error { - Error::Uncategorized("missing field".to_string()) - } - - fn unknown_field(_field: &str) -> Error { - Error::Uncategorized("unknown field".to_string()) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::std::error::Error::description(self).fmt(f) - } -} - -impl From for Error { - fn from(err: FixedValueReadError) -> Error { - match err { - FixedValueReadError::UnexpectedEOF => Error::InvalidMarkerRead(ReadError::UnexpectedEOF), - FixedValueReadError::Io(err) => Error::InvalidMarkerRead(ReadError::Io(err)), - FixedValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), - } - } -} - -impl From for Error { - fn from(err: ValueReadError) -> Error { - match err { - ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), - ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), - } - } -} - -/// Unstable: docs; incomplete -impl<'a> From> for Error { - fn from(err: DecodeStringError) -> Error { - match err { - DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()), - DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()), - DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()), - DecodeStringError::InvalidDataCopy(..) => Error::Uncategorized("InvalidDataCopy".to_string()), - DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()), - } - } -} - -impl From for Error { - fn from(err: MarkerReadError) -> Error { - Error::InvalidMarkerRead(From::from(err)) - } -} - -pub type Result = result::Result; - -/// # Note -/// -/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying -/// operation is retried. -// TODO: Docs. Examples. -pub struct Deserializer { - rd: R, - buf: Vec, -} - -impl Deserializer { - // TODO: Docs. - pub fn new(rd: R) -> Deserializer { - Deserializer { - rd: rd, - buf: Vec::new(), - } - } - - /// Gets a reference to the underlying reader in this decoder. - pub fn get_ref(&self) -> &R { - &self.rd - } - - /// Gets a mutable reference to the underlying reader in this decoder. - pub fn get_mut(&mut self) -> &mut R { - &mut self.rd - } - - /// Consumes this decoder returning the underlying reader. - pub fn into_inner(self) -> R { - self.rd - } - - fn read_str(&mut self, len: u32, mut visitor: V) -> Result - where V: serde::de::Visitor - { - self.buf.clear(); - self.buf.extend((0..len).map(|_| 0)); - visitor.visit_str(try!(read_str_data(&mut self.rd, len, &mut self.buf[..]))) - } - - fn read_array(&mut self, len: u32, mut visitor: V) -> Result - where V: serde::de::Visitor - { - visitor.visit_seq(SeqVisitor { - deserializer: self, - len: len, - actual: len, - }) - } - - fn read_map(&mut self, len: u32, mut visitor: V) -> Result - where V: serde::de::Visitor - { - visitor.visit_map(MapVisitor { - deserializer: self, - len: len, - actual: len, - }) - } - - fn read_bin_data(&mut self, len: usize, mut visitor: V) -> Result - where V: serde::de::Visitor - { - self.buf.clear(); - self.buf.extend((0..len).map(|_| 0)); - - match read_full(&mut self.rd, &mut self.buf[..]) { - Ok(n) if n == self.buf.len() => (), - Ok(..) => return Err(Error::InvalidDataRead(ReadError::UnexpectedEOF)), - Err(err) => return Err(Error::InvalidDataRead(ReadError::Io(err))), - } - - visitor.visit_bytes(&mut self.buf[..]) - } -} - -/// Unstable: docs; examples; incomplete -impl serde::Deserializer for Deserializer { - type Error = Error; - - fn visit(&mut self, mut visitor: V) -> Result - where V: serde::de::Visitor - { - match try!(read_marker(&mut self.rd)) { - Marker::Null => visitor.visit_unit(), - Marker::True => visitor.visit_bool(true), - Marker::False => visitor.visit_bool(false), - Marker::FixPos(val) => visitor.visit_u8(val), - Marker::FixNeg(val) => visitor.visit_i8(val), - Marker::U8 => visitor.visit_u8(try!(read_numeric_data(&mut self.rd))), - Marker::U16 => visitor.visit_u16(try!(read_numeric_data(&mut self.rd))), - Marker::U32 => visitor.visit_u32(try!(read_numeric_data(&mut self.rd))), - Marker::U64 => visitor.visit_u64(try!(read_numeric_data(&mut self.rd))), - Marker::I8 => visitor.visit_i8(try!(read_numeric_data(&mut self.rd))), - Marker::I16 => visitor.visit_i16(try!(read_numeric_data(&mut self.rd))), - Marker::I32 => visitor.visit_i32(try!(read_numeric_data(&mut self.rd))), - Marker::I64 => visitor.visit_i64(try!(read_numeric_data(&mut self.rd))), - Marker::F32 => visitor.visit_f32(try!(read_numeric_data(&mut self.rd))), - Marker::F64 => visitor.visit_f64(try!(read_numeric_data(&mut self.rd))), - Marker::FixStr(len) => self.read_str(len as u32, visitor), - Marker::Str8 => { - let len: u8 = try!(read_numeric_data(&mut self.rd)); - self.read_str(len as u32, visitor) - } - Marker::Str16 => { - let len: u16 = try!(read_numeric_data(&mut self.rd)); - self.read_str(len as u32, visitor) - } - Marker::Str32 => { - let len: u32 = try!(read_numeric_data(&mut self.rd)); - self.read_str(len, visitor) - } - Marker::FixArray(len) => { - self.read_array(len as u32, visitor) - } - Marker::Array16 => { - let len: u16 = try!(read_numeric_data(&mut self.rd)); - self.read_array(len as u32, visitor) - } - Marker::Array32 => { - let len: u32 = try!(read_numeric_data(&mut self.rd)); - self.read_array(len, visitor) - } - Marker::FixMap(len) => { - self.read_map(len as u32, visitor) - } - Marker::Map16 => { - let len: u16 = try!(read_numeric_data(&mut self.rd)); - self.read_map(len as u32, visitor) - } - Marker::Map32 => { - let len: u32 = try!(read_numeric_data(&mut self.rd)); - self.read_map(len, visitor) - } - Marker::Bin8 => { - let len: u8 = try!(read_numeric_data(&mut self.rd)); - self.read_bin_data(len as usize, visitor) - } - Marker::Bin16 => { - let len: u16 = try!(read_numeric_data(&mut self.rd)); - self.read_bin_data(len as usize, visitor) - } - Marker::Bin32 => { - let len: u32 = try!(read_numeric_data(&mut self.rd)); - self.read_bin_data(len as usize, visitor) - } - Marker::Reserved => Err(Error::TypeMismatch(Marker::Reserved)), - // TODO: Make something with exts. - marker => Err(From::from(FixedValueReadError::TypeMismatch(marker))), - } - } - - /// We treat Value::Null as None. - fn visit_option(&mut self, mut visitor: V) -> Result - where V: serde::de::Visitor, - { - // Primarily try to read optimisticly. - match visitor.visit_some(self) { - Ok(val) => Ok(val), - Err(Error::TypeMismatch(Marker::Null)) => visitor.visit_none(), - Err(err) => Err(err) - } - } -} - -struct SeqVisitor<'a, R: Read + 'a> { - deserializer: &'a mut Deserializer, - len: u32, - actual: u32, -} - -impl<'a, R: Read + 'a> serde::de::SeqVisitor for SeqVisitor<'a, R> { - type Error = Error; - - fn visit(&mut self) -> Result> - where T: serde::de::Deserialize, - { - if self.len > 0 { - self.len -= 1; - let value = try!(serde::Deserialize::deserialize(self.deserializer)); - Ok(Some(value)) - } else { - Ok(None) - } - } - - fn end(&mut self) -> Result<()> { - if self.len == 0 { - Ok(()) - } else { - Err(Error::LengthMismatch(self.actual)) - } - } -} - -struct MapVisitor<'a, R: Read + 'a> { - deserializer: &'a mut Deserializer, - len: u32, - actual: u32, -} - -impl<'a, R: Read + 'a> serde::de::MapVisitor for MapVisitor<'a, R> { - type Error = Error; - - fn visit_key(&mut self) -> Result> - where K: serde::de::Deserialize, - { - if self.len > 0 { - self.len -= 1; - let key = try!(serde::Deserialize::deserialize(self.deserializer)); - Ok(Some(key)) - } else { - Ok(None) - } - } - - fn visit_value(&mut self) -> Result - where V: serde::de::Deserialize, - { - let value = try!(serde::Deserialize::deserialize(self.deserializer)); - Ok(value) - } - - fn end(&mut self) -> Result<()> { - if self.len == 0 { - Ok(()) - } else { - Err(Error::LengthMismatch(self.actual)) - } - } -} - -} - pub use self::value::read_value; diff --git a/rmp/src/encode.rs b/rmp/src/encode.rs index e722f756..393538f2 100644 --- a/rmp/src/encode.rs +++ b/rmp/src/encode.rs @@ -17,7 +17,7 @@ pub mod value_ref; /// Represents an error that can occur when attempting to write MessagePack'ed value into the write. #[derive(Debug)] -pub struct WriteError(io::Error); +pub struct WriteError(pub io::Error); impl Error for WriteError { fn description(&self) -> &str { "error while writing MessagePack'ed value" } @@ -900,307 +900,3 @@ pub fn write_value(wr: &mut W, val: &Value) -> Result<(), Error> } } // mod value - -pub mod serde { - -use serde; - -use std::fmt; -use std::io::Write; - -use super::{ - write_nil, - write_bool, - write_uint, - write_sint, - write_f32, - write_f64, - write_str, - write_array_len, - write_map_len, - write_bin_len, -}; - -use super::{ - WriteError, - FixedValueWriteError, - ValueWriteError, -}; - -#[derive(Debug)] -pub enum Error { - /// Failed to write MessagePack'ed single-byte value into the write. - InvalidFixedValueWrite(WriteError), - InvalidValueWrite(ValueWriteError), -} - -impl ::std::error::Error for Error { - fn description(&self) -> &str { "an error occurred while writing encoded value" } - - fn cause(&self) -> Option<&::std::error::Error> { - match *self { - Error::InvalidFixedValueWrite(ref err) => Some(err), - Error::InvalidValueWrite(ref err) => Some(err), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::std::error::Error::description(self).fmt(f) - } -} - - -impl From for Error { - fn from(err: FixedValueWriteError) -> Error { - match err { - FixedValueWriteError(err) => Error::InvalidFixedValueWrite(err) - } - } -} - -impl From for Error { - fn from(err: ValueWriteError) -> Error { - Error::InvalidValueWrite(err) - } -} - -/// Represents MessagePack serialization implementation. -/// -/// # Note -/// -/// MessagePack has no specification about how to encode variant types. Thus we are free to do -/// whatever we want, so the given chose may be not ideal for you. -/// -/// Every Rust variant value can be represented as a tuple of index and a value. -/// -/// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying -/// operation is retried. -// TODO: Docs. Examples. -pub struct Serializer<'a> { - wr: &'a mut Write, -} - -impl<'a> Serializer<'a> { - /// Creates a new MessagePack encoder whose output will be written to the writer specified. - pub fn new(wr: &'a mut Write) -> Serializer<'a> { - Serializer { - wr: wr, - } - } -} - -impl<'a> serde::Serializer for Serializer<'a> { - type Error = Error; - - fn visit_unit(&mut self) -> Result<(), Error> { - write_nil(&mut self.wr).map_err(From::from) - } - - fn visit_bool(&mut self, val: bool) -> Result<(), Error> { - write_bool(&mut self.wr, val).map_err(From::from) - } - - fn visit_u8(&mut self, val: u8) -> Result<(), Error> { - self.visit_u64(val as u64) - } - - fn visit_u16(&mut self, val: u16) -> Result<(), Error> { - self.visit_u64(val as u64) - } - - fn visit_u32(&mut self, val: u32) -> Result<(), Error> { - self.visit_u64(val as u64) - } - - fn visit_u64(&mut self, val: u64) -> Result<(), Error> { - try!(write_uint(&mut self.wr, val)); - - Ok(()) - } - - fn visit_usize(&mut self, val: usize) -> Result<(), Error> { - self.visit_u64(val as u64) - } - - fn visit_i8(&mut self, val: i8) -> Result<(), Error> { - self.visit_i64(val as i64) - } - - fn visit_i16(&mut self, val: i16) -> Result<(), Error> { - self.visit_i64(val as i64) - } - - fn visit_i32(&mut self, val: i32) -> Result<(), Error> { - self.visit_i64(val as i64) - } - - fn visit_i64(&mut self, val: i64) -> Result<(), Error> { - try!(write_sint(&mut self.wr, val)); - - Ok(()) - } - - fn visit_isize(&mut self, val: isize) -> Result<(), Error> { - self.visit_i64(val as i64) - } - - fn visit_f32(&mut self, val: f32) -> Result<(), Error> { - write_f32(&mut self.wr, val).map_err(From::from) - } - - fn visit_f64(&mut self, val: f64) -> Result<(), Error> { - write_f64(&mut self.wr, val).map_err(From::from) - } - - // TODO: The implementation involves heap allocation and is unstable. - fn visit_char(&mut self, val: char) -> Result<(), Error> { - let mut buf = String::new(); - buf.push(val); - self.visit_str(&buf) - } - - fn visit_str(&mut self, val: &str) -> Result<(), Error> { - write_str(&mut self.wr, val).map_err(From::from) - } - - fn visit_unit_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str) -> Result<(), Error> - { - // Mark that we want to encode a variant type. - try!(write_array_len(&mut self.wr, 2)); - - // Encode a value position... - try!(self.visit_usize(variant_index)); - - // ... and its arguments length. - try!(write_array_len(&mut self.wr, 0)); - - Ok(()) - } - - /// Encodes and attempts to write the enum value into the Write. - /// - /// Currently we encode variant types as a tuple of id with array of args, like: [id, [args...]] - fn visit_tuple_variant(&mut self, - _name: &str, - variant_index: usize, - _variant: &str, - mut visitor: V) -> Result<(), Error> - where V: serde::ser::SeqVisitor, - { - // Mark that we want to encode a variant type. - try!(write_array_len(&mut self.wr, 2)); - - // Encode a value position... - try!(self.visit_usize(variant_index)); - - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a sequence with no length"), - }; - - // ... and its arguments length. - try!(write_array_len(&mut self.wr, len as u32)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) - } - - fn visit_struct_variant(&mut self, - _name: &str, - _variant_index: usize, - _variant: &str, - _visitor: V) -> Result<(), Error> - where V: serde::ser::MapVisitor, - { - unimplemented!() - } - - fn visit_none(&mut self) -> Result<(), Error> { - self.visit_unit() - } - - fn visit_some(&mut self, v: T) -> Result<(), Error> - where T: serde::Serialize, - { - v.serialize(self) - } - - // TODO: Check len, overflow is possible. - fn visit_seq(&mut self, mut visitor: V) -> Result<(), Error> - 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!(write_array_len(&mut self.wr, len as u32)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) - } - - fn visit_seq_elt(&mut self, value: V) -> Result<(), Error> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn visit_map(&mut self, mut visitor: V) -> Result<(), Error> - 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!(write_map_len(&mut self.wr, len as u32)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) - } - - fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Error> - where K: serde::Serialize, - V: serde::Serialize, - { - try!(key.serialize(self)); - value.serialize(self) - } - - fn visit_struct(&mut self, _name: &str, mut visitor: V) -> Result<(), Error> - where V: serde::ser::MapVisitor, - { - let len = match visitor.len() { - Some(len) => len, - None => panic!("do not know how to serialize a sequence with no length"), - }; - - try!(write_array_len(&mut self.wr, len as u32)); - - while let Some(()) = try!(visitor.visit(self)) { } - - Ok(()) - } - - fn visit_struct_elt(&mut self, _key: &str, value: V) -> Result<(), Error> - where V: serde::Serialize, - { - value.serialize(self) - } - - fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Error> { - try!(write_bin_len(&mut self.wr, value.len() as u32)); - self.wr.write_all(value).map_err(|err| Error::InvalidValueWrite(ValueWriteError::InvalidDataWrite(WriteError(err)))) - } -} - -} diff --git a/rmp/src/lib.rs b/rmp/src/lib.rs index 9762dfd3..9f257dd9 100644 --- a/rmp/src/lib.rs +++ b/rmp/src/lib.rs @@ -46,8 +46,6 @@ extern crate byteorder; -extern crate serde; - pub mod encode; pub mod decode; @@ -57,9 +55,6 @@ pub mod value; pub const MSGPACK_VERSION : u32 = 5; -pub use decode::serde::Deserializer; -pub use encode::serde::Serializer; - pub use init::Marker; pub use value::{Value, ValueRef}; diff --git a/rmp/tests/func/decode/deserializer.rs b/rmp/tests/func/decode/deserializer.rs deleted file mode 100644 index 2c597932..00000000 --- a/rmp/tests/func/decode/deserializer.rs +++ /dev/null @@ -1,516 +0,0 @@ -mod null { - use std::io::Cursor; - - use serde::Deserialize; - - use msgpack::Deserializer; - - #[test] - fn pass() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!((), Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - mod fail { - use std::io::Cursor; - use std::result; - - use serde::Deserialize; - - use msgpack::Deserializer; - use msgpack::Marker; - use msgpack::decode::serde::Error; - - type Result = result::Result; - - #[test] - fn from_reserved() { - let buf = [0xc1]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - let res: Result<()> = Deserialize::deserialize(&mut deserializer); - match res.err() { - Some(Error::TypeMismatch(Marker::Reserved)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - } // mod fail -} // mod null - -mod bool { - use std::io::Cursor; - - use serde::Deserialize; - - use msgpack::Deserializer; - - #[test] - fn pass() { - let buf = [0xc2, 0xc3]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(false, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - assert_eq!(true, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - mod fail { - use std::io::Cursor; - use std::result; - - use serde::Deserialize; - - use msgpack::Deserializer; - use msgpack::Marker; - use msgpack::decode::serde::Error; - - type Result = result::Result; - - #[test] - fn from_fixint() { - let buf = [0x00]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - let res: Result = Deserialize::deserialize(&mut deserializer); - match res.err() { - Some(Error::TypeMismatch(Marker::U64)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - } -} - -mod unspecified { - use std::io::Cursor; - use std::result; - - use serde::Deserialize; - - use msgpack::Deserializer; - use msgpack::Marker; - use msgpack::decode::serde::Error; - - type Result = result::Result; - - #[test] - fn pass_u64() { - let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(18446744073709551615u64, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_u32() { - let buf = [0xce, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(4294967295u32, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn fail_u32_from_u64() { - let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - let res: Result = Deserialize::deserialize(&mut deserializer); - match res.err() { - Some(Error::TypeMismatch(Marker::U64)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_u16() { - let buf = [0xcd, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(65535u16, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_u8() { - let buf = [0xcc, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(255u8, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_usize() { - let buf = [0xcc, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(255usize, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_i64() { - let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(9223372036854775807i64, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_i32() { - let buf = [0xd2, 0x7f, 0xff, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(2147483647i32, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_i16() { - let buf = [0xd1, 0x7f, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(32767i16, Deserialize::deserialize(&mut deserializer).ok().unwrap()); - } - - #[test] - fn pass_i8() { - let buf = [0xd0, 0x7f]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(127i8, Deserialize::deserialize(&mut deserializer).unwrap()); - } - - #[test] - fn pass_isize() { - let buf = [0xd0, 0x7f]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(127isize, Deserialize::deserialize(&mut deserializer).unwrap()); - } - - #[test] - fn pass_f32() { - let buf = [0xca, 0x7f, 0x7f, 0xff, 0xff]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(3.4028234e38_f32, Deserialize::deserialize(&mut deserializer).unwrap()); - } - - #[test] - fn pass_f64() { - let buf = [0xcb, 0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - - assert_eq!(42f64, Deserialize::deserialize(&mut deserializer).unwrap()); - } - - #[test] - fn pass_string() { - let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: String = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!("le message".to_string(), actual); - } - - #[test] - fn pass_tuple() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: (u32, u32) = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!((42, 100500), actual); - } - - #[test] - fn fail_tuple_len_mismatch() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Result<(u32,)> = Deserialize::deserialize(&mut deserializer); - - match actual.err() { - Some(Error::LengthMismatch(2)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[cfg(feature = "serde_macros")] - #[test] - fn pass_tuple_struct() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - struct Decoded(u32, u32); - - let mut deserializer = Deserializer::new(cur); - let actual: Decoded = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(Decoded(42, 100500), actual); - } - - #[cfg(feature = "serde_macros")] - #[test] - fn pass_struct() { - let buf = [0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - struct Decoded { id: u32, value: u32 }; - - let mut deserializer = Deserializer::new(cur); - let actual: Decoded = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(Decoded { id: 42, value: 100500 }, actual); - } - - #[test] - fn pass_option_some() { - let buf = [0x1f]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Option = Deserialize::deserialize(&mut deserializer).unwrap(); - assert_eq!(Some(31), actual); - } - - #[test] - fn pass_option_some_null() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Option<()> = Deserialize::deserialize(&mut deserializer).unwrap(); - assert_eq!(Some(()), actual); - } - - #[test] - fn pass_option_none() { - let buf = [0xc0]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Option = Deserialize::deserialize(&mut deserializer).unwrap(); - assert_eq!(None, actual); - } - - #[test] - fn fail_option_u8_from_reserved() { - let buf = [0xc1]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Result> = Deserialize::deserialize(&mut deserializer); - match actual.err() { - Some(Error::TypeMismatch(Marker::Reserved)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[test] - fn pass_vector() { - let buf = [0x92, 0x00, 0xcc, 0x80]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: Vec = Deserialize::deserialize(&mut deserializer).unwrap(); - assert_eq!(vec![0, 128], actual); - } - - #[test] - fn pass_map() { - use std::collections::HashMap; - - let buf = [ - 0x82, // 2 (size) - 0xa3, 0x69, 0x6e, 0x74, // 'int' - 0xcc, 0x80, // 128 - 0xa3, 0x6b, 0x65, 0x79, // 'key' - 0x2a // 42 - ]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: HashMap = Deserialize::deserialize(&mut deserializer).unwrap(); - let mut expected = HashMap::new(); - expected.insert("int".to_string(), 128); - expected.insert("key".to_string(), 42); - - assert_eq!(expected, actual); - } - - #[cfg(feature = "serde_macros")] - #[test] - fn pass_enum() { - let buf = [0x92, 0x01, 0x90]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - enum Custom { - First, - Second, - } - - let mut deserializer = Deserializer::new(cur); - let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(Custom::Second, actual); - } - - #[cfg(feature = "serde_macros")] - #[test] - fn pass_enum_variant_with_arg() { - let buf = [0x92, 0x01, 0x91, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - enum Custom { - First, - Second(u32), - } - - let mut deserializer = Deserializer::new(cur); - let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(Custom::Second(42), actual); - } - - #[cfg(feature = "serde_macros")] - #[test] - fn fail_enum_sequence_mismatch() { - let buf = [0x93, 0x1, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - enum Custom { - First, - Second, - } - - let mut deserializer = Deserializer::new(cur); - let actual: Result = Deserialize::deserialize(&mut deserializer); - - match actual.err() { - Some(Error::Uncategorized(..)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[cfg(feature = "serde_macros")] - #[test] - fn fail_enum_overflow() { - let buf = [0x92, 0x01, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - enum Custom { - First, - } - - let mut deserializer = Deserializer::new(cur); - let actual: Result = Deserialize::deserialize(&mut deserializer); - - match actual.err() { - Some(Error::Uncategorized(..)) => (), - other => panic!("unexpected result: {:?}", other) - } - } - - #[cfg(feature = "serde_macros")] - #[test] - fn pass_struct_enum_with_arg() { - let buf = [0x92, 0x01, 0x91, 0x2a]; - let cur = Cursor::new(&buf[..]); - - #[derive(Debug, PartialEq, Deserialize)] - enum Custom { - First, - Second { id: u32 }, - } - - let mut deserializer = Deserializer::new(cur); - let actual: Custom = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(Custom::Second { id: 42 }, actual); - } - - // TODO: Merge three of them. - #[test] - fn pass_bin8_into_bytebuf() { - use serde::bytes::ByteBuf; - - let buf = [0xc4, 0x02, 0xcc, 0x80]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); - let actual: Vec = actual.into(); - - assert_eq!(vec![0xcc, 0x80], actual); - } - - #[test] - fn pass_bin16_into_bytebuf() { - use serde::bytes::ByteBuf; - - let buf = [0xc5, 0x00, 0x02, 0xcc, 0x80]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); - let actual: Vec = actual.into(); - - assert_eq!(vec![0xcc, 0x80], actual); - } - - #[test] - fn pass_bin32_into_bytebuf() { - use serde::bytes::ByteBuf; - - let buf = [0xc6, 0x00, 0x00, 0x00, 0x02, 0xcc, 0x80]; - let cur = Cursor::new(&buf[..]); - - let mut deserializer = Deserializer::new(cur); - let actual: ByteBuf = Deserialize::deserialize(&mut deserializer).unwrap(); - let actual: Vec = actual.into(); - - assert_eq!(vec![0xcc, 0x80], actual); - } -} diff --git a/rmp/tests/func/decode/mod.rs b/rmp/tests/func/decode/mod.rs index 66551409..52aae04a 100644 --- a/rmp/tests/func/decode/mod.rs +++ b/rmp/tests/func/decode/mod.rs @@ -10,6 +10,5 @@ mod map; mod ext; // High-level deserialize interface. -mod deserializer; mod value; mod value_ref; diff --git a/rmp/tests/func/encode/mod.rs b/rmp/tests/func/encode/mod.rs index c138c98d..e960bc4e 100644 --- a/rmp/tests/func/encode/mod.rs +++ b/rmp/tests/func/encode/mod.rs @@ -10,6 +10,5 @@ mod map; mod ext; // High-level serialize interface. -mod serializer; mod value; mod value_ref; diff --git a/rmp/tests/func/mod.rs b/rmp/tests/func/mod.rs index d6b65bc4..11c3e64f 100644 --- a/rmp/tests/func/mod.rs +++ b/rmp/tests/func/mod.rs @@ -1,3 +1,2 @@ mod encode; mod decode; -mod serde; diff --git a/rmp/tests/lib.rs b/rmp/tests/lib.rs index 067d49f6..f63e542c 100644 --- a/rmp/tests/lib.rs +++ b/rmp/tests/lib.rs @@ -1,7 +1,3 @@ -#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))] -#![cfg_attr(feature = "serde_macros", plugin(serde_macros))] - extern crate rmp as msgpack; -extern crate serde; mod func; From 2b9d2b9e5a180fee7bc3a96e68a86606e95ad3a8 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 12:49:57 +0300 Subject: [PATCH 11/12] CI: fix coveralls, drop build for 1.1. --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 80e3cbb9..12cf618c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ addons: - libdw-dev rust: - - 1.1.0 - stable - beta - nightly @@ -26,8 +25,8 @@ before_script: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - - cd $CRATE && cargo test + - (cd $CRATE && cargo test) # Measure code coverage and upload to coveralls.io. after_success: - - cd $CRATE && travis-cargo coveralls --no-sudo + - (cd $CRATE && travis-cargo coveralls --no-sudo) From a7c9b384b2cae82acaf87c9f7e5520d0e7c56007 Mon Sep 17 00:00:00 2001 From: Evgeny Safronov Date: Mon, 24 Aug 2015 15:36:25 +0300 Subject: [PATCH 12/12] Version: bumped. --- CHANGELOG.md | 2 ++ README.md | 2 +- rmp-serde/Cargo.toml | 2 +- rmp-serialize/Cargo.toml | 2 +- rmp/Cargo.toml | 2 +- rmp/src/lib.rs | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b7bbab7..c7aff3ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][unreleased] + +## 0.7.0 - 2015-08-24 ### Changed - The big single crate has been refactored, which results in three crates: `rmp`, `rmp-serialize` and `rmp-serde`. diff --git a/README.md b/README.md index 3decf688..79ed8939 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ To use `rmp`, first add this to your `Cargo.toml`: ```toml [dependencies.rmp] -rmp = "0.6.0" +rmp = "0.7.0" ``` Then, add this to your crate root: diff --git a/rmp-serde/Cargo.toml b/rmp-serde/Cargo.toml index d3dffbe4..b4aa123c 100644 --- a/rmp-serde/Cargo.toml +++ b/rmp-serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmp-serde" -version = "0.6.0" +version = "0.7.0" authors = ["Evgeny Safronov "] license = "MIT" description = "Serde bindings for RMP" diff --git a/rmp-serialize/Cargo.toml b/rmp-serialize/Cargo.toml index 05b15bbd..33c11d13 100644 --- a/rmp-serialize/Cargo.toml +++ b/rmp-serialize/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmp-serialize" -version = "0.6.0" +version = "0.7.0" authors = ["Evgeny Safronov "] license = "MIT" description = "Rust Serialize bindings for RMP" diff --git a/rmp/Cargo.toml b/rmp/Cargo.toml index 25913f9b..98977672 100644 --- a/rmp/Cargo.toml +++ b/rmp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmp" -version = "0.6.0" +version = "0.7.0" authors = ["Evgeny Safronov "] license = "MIT" description = "Pure Rust MessagePack serialization implementation" diff --git a/rmp/src/lib.rs b/rmp/src/lib.rs index 9f257dd9..6901b122 100644 --- a/rmp/src/lib.rs +++ b/rmp/src/lib.rs @@ -12,7 +12,7 @@ //! //! ```toml //! [dependencies.rmp] -//! rmp = "0.6.0" +//! rmp = "0.7.0" //! ``` //! //! Then, add this to your crate root: