use byteorder::BigEndian;
use byteorder::{self, ReadBytesExt};
pub use msgpack_schema_impl::*;
use msgpack_value::Value;
use msgpack_value::{Bin, Ext, Int, Str};
use std::convert::TryFrom;
use std::convert::TryInto;
use std::io::Write;
use thiserror::Error;
pub struct Serializer {
w: Vec<u8>,
}
impl Serializer {
fn new() -> Self {
Self { w: vec![] }
}
fn with_vec(w: Vec<u8>) -> Self {
Self { w }
}
fn into_inner(self) -> Vec<u8> {
self.w
}
pub fn serialize_nil(&mut self) {
rmp::encode::write_nil(&mut self.w).unwrap()
}
pub fn serialize_bool(&mut self, v: bool) {
rmp::encode::write_bool(&mut self.w, v).unwrap()
}
pub fn serialize_int(&mut self, v: Int) {
if let Ok(v) = i64::try_from(v) {
rmp::encode::write_sint(&mut self.w, v).unwrap();
} else {
rmp::encode::write_uint(&mut self.w, u64::try_from(v).unwrap()).unwrap();
}
}
pub fn serialize_f32(&mut self, v: f32) {
rmp::encode::write_f32(&mut self.w, v).unwrap();
}
pub fn serialize_f64(&mut self, v: f64) {
rmp::encode::write_f64(&mut self.w, v).unwrap();
}
pub fn serialize_str(&mut self, v: &[u8]) {
rmp::encode::write_str_len(&mut self.w, v.len() as u32).unwrap();
self.w.write_all(v).unwrap();
}
pub fn serialize_bin(&mut self, v: &[u8]) {
rmp::encode::write_bin(&mut self.w, v).unwrap();
}
pub fn serialize_array(&mut self, len: u32) {
rmp::encode::write_array_len(&mut self.w, len).unwrap();
}
pub fn serialize_map(&mut self, len: u32) {
rmp::encode::write_map_len(&mut self.w, len).unwrap();
}
pub fn serialize_ext(&mut self, tag: i8, data: &[u8]) {
rmp::encode::write_ext_meta(&mut self.w, data.len() as u32, tag).unwrap();
self.w.write_all(data).unwrap();
}
pub fn serialize<S: Serialize>(&mut self, s: S) {
S::serialize(&s, self)
}
}
pub trait Serialize {
fn serialize(&self, serializer: &mut Serializer);
}
impl<T: Serialize> Serialize for &T {
fn serialize(&self, serializer: &mut Serializer) {
T::serialize(*self, serializer)
}
}
impl Serialize for bool {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_bool(*self)
}
}
impl Serialize for Int {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(*self)
}
}
impl Serialize for u8 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for u16 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for u32 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for u64 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for i8 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for i16 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for i32 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for i64 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_int(Int::from(*self))
}
}
impl Serialize for f32 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_f32(*self)
}
}
impl Serialize for f64 {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_f64(*self)
}
}
impl Serialize for Str {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_str(&self.0)
}
}
impl Serialize for str {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_str(self.as_bytes())
}
}
impl Serialize for String {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_str(self.as_bytes())
}
}
impl<T: Serialize> Serialize for [T] {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_array(self.len() as u32);
for x in self {
serializer.serialize(x);
}
}
}
impl<T: Serialize> Serialize for Vec<T> {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_array(self.len() as u32);
for x in self {
serializer.serialize(x);
}
}
}
impl<T: Serialize> Serialize for Box<T> {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize(&**self);
}
}
impl<T: Serialize> Serialize for std::rc::Rc<T> {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize(&**self);
}
}
impl<T: Serialize> Serialize for std::sync::Arc<T> {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize(&**self);
}
}
#[doc(hidden)]
pub trait StructSerialize: Serialize {
fn count_fields(&self) -> u32;
fn serialize_fields(&self, serializer: &mut Serializer);
}
#[derive(Debug, Clone, PartialEq)]
pub enum Token<'a> {
Nil,
Bool(bool),
Int(Int),
F32(f32),
F64(f64),
Str(&'a [u8]),
Bin(&'a [u8]),
Array(u32),
Map(u32),
Ext { tag: i8, data: &'a [u8] },
}
#[derive(Debug, Error)]
#[error("invalid input")]
pub struct InvalidInputError;
#[derive(Clone, Copy)]
pub struct Deserializer<'a> {
r: &'a [u8],
}
impl<'a> Deserializer<'a> {
fn new(r: &'a [u8]) -> Self {
Self { r }
}
pub fn deserialize_token(&mut self) -> Result<Token, InvalidInputError> {
let token = match rmp::decode::read_marker(&mut self.r).map_err(|_| InvalidInputError)? {
rmp::Marker::Null => Token::Nil,
rmp::Marker::True => Token::Bool(true),
rmp::Marker::False => Token::Bool(false),
rmp::Marker::FixPos(v) => Token::Int(Int::from(v)),
rmp::Marker::FixNeg(v) => Token::Int(Int::from(v)),
rmp::Marker::U8 => {
Token::Int(Int::from(self.r.read_u8().map_err(|_| InvalidInputError)?))
}
rmp::Marker::U16 => Token::Int(Int::from(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::U32 => Token::Int(Int::from(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::U64 => Token::Int(Int::from(
self.r
.read_u64::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::I8 => {
Token::Int(Int::from(self.r.read_i8().map_err(|_| InvalidInputError)?))
}
rmp::Marker::I16 => Token::Int(Int::from(
self.r
.read_i16::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::I32 => Token::Int(Int::from(
self.r
.read_i32::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::I64 => Token::Int(Int::from(
self.r
.read_i64::<BigEndian>()
.map_err(|_| InvalidInputError)?,
)),
rmp::Marker::F32 => Token::F32(
self.r
.read_f32::<BigEndian>()
.map_err(|_| InvalidInputError)?,
),
rmp::Marker::F64 => Token::F64(
self.r
.read_f64::<BigEndian>()
.map_err(|_| InvalidInputError)?,
),
rmp::Marker::FixStr(len) => {
let len = len as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Str(ret)
}
rmp::Marker::Str8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Str(ret)
}
rmp::Marker::Str16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Str(ret)
}
rmp::Marker::Str32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Str(ret)
}
rmp::Marker::Bin8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Bin(ret)
}
rmp::Marker::Bin16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Bin(ret)
}
rmp::Marker::Bin32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let ret = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Bin(ret)
}
rmp::Marker::FixArray(len) => Token::Array(len as u32),
rmp::Marker::Array16 => Token::Array(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)? as u32,
),
rmp::Marker::Array32 => Token::Array(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)?,
),
rmp::Marker::FixMap(len) => Token::Map(len as u32),
rmp::Marker::Map16 => Token::Map(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)? as u32,
),
rmp::Marker::Map32 => Token::Map(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)?,
),
rmp::Marker::FixExt1 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..1).ok_or(InvalidInputError)?;
self.r = self.r.get(1..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::FixExt2 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..2).ok_or(InvalidInputError)?;
self.r = self.r.get(2..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::FixExt4 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..4).ok_or(InvalidInputError)?;
self.r = self.r.get(4..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::FixExt8 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..8).ok_or(InvalidInputError)?;
self.r = self.r.get(8..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::FixExt16 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..16).ok_or(InvalidInputError)?;
self.r = self.r.get(16..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::Ext8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError)? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::Ext16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::Ext32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError)? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError)?;
let data = self.r.get(0..len).ok_or(InvalidInputError)?;
self.r = self.r.get(len..).unwrap();
Token::Ext { tag, data }
}
rmp::Marker::Reserved => return Err(InvalidInputError),
};
Ok(token)
}
pub fn deserialize<D: Deserialize>(&mut self) -> Result<D, DeserializeError> {
D::deserialize(self)
}
pub fn try_deserialize<D: Deserialize>(&mut self) -> Result<Option<D>, InvalidInputError> {
let mut branch = *self;
match branch.deserialize() {
Ok(v) => {
*self = branch;
Ok(Some(v))
}
Err(DeserializeError::Validation(_)) => Ok(None),
Err(DeserializeError::InvalidInput(err)) => Err(err),
}
}
pub fn deserialize_any(&mut self) -> Result<(), DeserializeError> {
let mut count = 1;
while count > 0 {
count -= 1;
match self.deserialize_token()? {
Token::Nil
| Token::Bool(_)
| Token::Int(_)
| Token::F32(_)
| Token::F64(_)
| Token::Str(_)
| Token::Bin(_)
| Token::Ext { .. } => {}
Token::Array(len) => {
count += len;
}
Token::Map(len) => {
count += len * 2;
}
}
}
Ok(())
}
}
#[derive(Debug, Error)]
#[error("validation failed")]
pub struct ValidationError;
#[derive(Debug, Error)]
pub enum DeserializeError {
#[error(transparent)]
InvalidInput(#[from] InvalidInputError),
#[error(transparent)]
Validation(#[from] ValidationError),
}
pub trait Deserialize: Sized {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError>;
}
impl Deserialize for bool {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::Bool(v) = deserializer.deserialize_token()? {
return Ok(v);
}
Err(ValidationError.into())
}
}
impl Deserialize for Int {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::Int(v) = deserializer.deserialize_token()? {
return Ok(v);
}
Err(ValidationError.into())
}
}
impl Deserialize for u8 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for u16 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for u32 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for u64 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for i8 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for i16 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for i32 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for i64 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize::<Int>()?
.try_into()
.map_err(|_| ValidationError.into())
}
}
impl Deserialize for f32 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::F32(v) = deserializer.deserialize_token()? {
return Ok(v);
}
Err(ValidationError.into())
}
}
impl Deserialize for f64 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::F64(v) = deserializer.deserialize_token()? {
return Ok(v);
}
Err(ValidationError.into())
}
}
impl Deserialize for Str {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::Str(v) = deserializer.deserialize_token()? {
return Ok(Str(v.to_vec()));
}
Err(ValidationError.into())
}
}
impl Deserialize for String {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let Str(data) = deserializer.deserialize()?;
let v = String::from_utf8(data).map_err(|_| ValidationError)?;
Ok(v)
}
}
impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Token::Array(len) = deserializer.deserialize_token()? {
let mut vec = Vec::with_capacity(len as usize);
for _ in 0..len {
vec.push(deserializer.deserialize()?);
}
return Ok(vec);
}
Err(ValidationError.into())
}
}
impl<T: Deserialize> Deserialize for Box<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
Ok(Box::new(deserializer.deserialize()?))
}
}
impl<T: Deserialize> Deserialize for std::rc::Rc<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
Ok(Self::new(deserializer.deserialize()?))
}
}
impl<T: Deserialize> Deserialize for std::sync::Arc<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
Ok(Self::new(deserializer.deserialize()?))
}
}
pub fn serialize<S: Serialize>(s: S) -> Vec<u8> {
let mut serializer = Serializer::new();
serializer.serialize(s);
serializer.into_inner()
}
pub fn serialize_into<S: Serialize>(s: S, buf: &mut Vec<u8>) {
let v = std::mem::take(buf);
let mut serializer = Serializer::with_vec(v);
serializer.serialize(s);
*buf = serializer.into_inner();
}
pub fn deserialize<D: Deserialize>(r: &[u8]) -> Result<D, DeserializeError> {
let mut deserializer = Deserializer::new(r);
deserializer.deserialize()
}
#[test]
fn deserialize_ignores_extra_bytes() {
let input: Vec<u8> = vec![0x01, 0xc1];
let v: Int = deserialize(&input).unwrap();
assert_eq!(v, Int::from(1u32));
}
impl Serialize for Value {
fn serialize(&self, serializer: &mut Serializer) {
match self {
Value::Nil => serializer.serialize_nil(),
Value::Bool(v) => serializer.serialize_bool(*v),
Value::Int(v) => serializer.serialize_int(*v),
Value::F32(v) => serializer.serialize_f32(*v),
Value::F64(v) => serializer.serialize_f64(*v),
Value::Str(v) => serializer.serialize_str(&v.0),
Value::Bin(v) => serializer.serialize_bin(&v.0),
Value::Array(v) => {
serializer.serialize_array(v.len() as u32);
for x in v {
serializer.serialize(x);
}
}
Value::Map(v) => {
serializer.serialize_map(v.len() as u32);
for (k, v) in v {
serializer.serialize(k);
serializer.serialize(v);
}
}
Value::Ext(v) => serializer.serialize_ext(v.r#type, &v.data),
}
}
}
impl Deserialize for Value {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let x = match deserializer.deserialize_token()? {
Token::Nil => Value::Nil,
Token::Bool(v) => v.into(),
Token::Int(v) => v.into(),
Token::F32(v) => v.into(),
Token::F64(v) => v.into(),
Token::Str(v) => Str(v.to_vec()).into(),
Token::Bin(v) => Bin(v.to_vec()).into(),
Token::Array(len) => {
let mut vec: Vec<Value> = vec![];
for _ in 0..len {
vec.push(deserializer.deserialize()?);
}
vec.into()
}
Token::Map(len) => {
let mut map: Vec<(Value, Value)> = vec![];
for _ in 0..len {
map.push((deserializer.deserialize()?, deserializer.deserialize()?));
}
map.into()
}
Token::Ext { tag, data } => Ext {
r#type: tag,
data: data.to_vec(),
}
.into(),
};
Ok(x)
}
}
#[doc(hidden)]
pub mod value {
use super::*;
pub use msgpack_value::{Bin, Ext, Int, Str, Value};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Nil;
impl Serialize for Nil {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_nil()
}
}
impl Deserialize for Nil {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let token = deserializer.deserialize_token()?;
if token != Token::Nil {
return Err(ValidationError.into());
}
Ok(Self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Any;
impl Deserialize for Any {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer.deserialize_any()?;
Ok(Any)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Empty {}
impl Serialize for Empty {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_map(0)
}
}
impl Deserialize for Empty {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let token = deserializer.deserialize_token()?;
if token != Token::Map(0) {
return Err(ValidationError.into());
}
Ok(Self {})
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use msgpack_value::msgpack;
use proptest::prelude::*;
use proptest_derive::Arbitrary;
macro_rules! roundtrip {
($name:ident, $ty:ty) => {
#[cfg(test)]
mod $name {
use super::*;
proptest! {
#[test]
fn test(v: $ty) {
assert_eq!(v, deserialize::<$ty>(serialize(&v).as_slice()).unwrap());
}
}
}
};
}
roundtrip!(roundtrip_bool, bool);
roundtrip!(roundtrip_i8, i8);
roundtrip!(roundtrip_i16, i16);
roundtrip!(roundtrip_i32, i32);
roundtrip!(roundtrip_i64, i64);
roundtrip!(roundtrip_u8, u8);
roundtrip!(roundtrip_u16, u16);
roundtrip!(roundtrip_u32, u32);
roundtrip!(roundtrip_u64, u64);
roundtrip!(roundtrip_f32, f32);
roundtrip!(roundtrip_f64, f64);
roundtrip!(roundtrip_str, String);
roundtrip!(roundtrip_blob, Vec<i32>);
roundtrip!(roundtrip_box, Box<i32>);
roundtrip!(roundtrip_rc, std::rc::Rc<i32>);
roundtrip!(roundtrip_arc, std::sync::Arc<i32>);
roundtrip!(roundtrip_value, Value);
roundtrip!(roundtrip_int, Int);
#[derive(Debug, PartialEq, Eq, Arbitrary)]
struct Human {
age: u32,
name: String,
}
impl Serialize for Human {
fn serialize(&self, serializer: &mut Serializer) {
serializer.serialize_map(2);
serializer.serialize(0u32);
serializer.serialize(self.age);
serializer.serialize(1u32);
serializer.serialize(&self.name);
}
}
impl Deserialize for Human {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let len = match deserializer.deserialize_token()? {
Token::Map(len) => len,
_ => return Err(ValidationError.into()),
};
let mut age: Option<u32> = None;
let mut name: Option<String> = None;
for _ in 0..len {
let tag: u32 = deserializer.deserialize()?;
match tag {
0 => {
if age.is_some() {
return Err(InvalidInputError.into());
}
age = Some(deserializer.deserialize()?);
}
1 => {
if name.is_some() {
return Err(InvalidInputError.into());
}
name = Some(deserializer.deserialize()?);
}
_ => {
deserializer.deserialize_any()?;
}
}
}
Ok(Self {
age: age.ok_or(ValidationError)?,
name: name.ok_or(ValidationError)?,
})
}
}
roundtrip!(roundtrip_human, Human);
fn check_serialize_result<T: Serialize>(x: T, v: Value) {
let buf1 = serialize(&x);
let buf2 = serialize(v);
assert_eq!(buf1, buf2);
}
#[test]
fn struct_vs_value() {
check_serialize_result(
Human {
age: 42,
name: "John".into(),
},
msgpack!({
0: 42,
1: "John",
}),
);
}
#[test]
fn box_vs_value() {
check_serialize_result(Box::new(42i32), msgpack!(42));
}
#[test]
fn rc_vs_value() {
check_serialize_result(std::rc::Rc::new(42i32), msgpack!(42));
}
#[test]
fn arc_vs_value() {
check_serialize_result(std::sync::Arc::new(42i32), msgpack!(42));
}
#[test]
fn serialize_into_keeps_buf() {
let mut buf = vec![0x12, 0x34, 0x56, 0x78];
serialize_into(42, &mut buf);
assert_eq!(*buf, [0x12, 0x34, 0x56, 0x78, 42]);
}
}