pub mod value;
use byteorder::BigEndian;
use byteorder::{self, ReadBytesExt};
pub use msgpack_schema_impl::*;
use std::convert::TryFrom;
use std::convert::TryInto;
use std::io::{self, Write};
use thiserror::Error;
use value::{Bin, Ext, Int, Nil, Str};
pub struct Serializer {
w: Vec<u8>,
}
impl Serializer {
fn new() -> Self {
Self { w: vec![] }
}
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 Option<T> {
fn serialize(&self, serializer: &mut Serializer) {
match self {
Some(v) => serializer.serialize(v),
None => serializer.serialize_nil(),
}
}
}
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);
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Token {
Nil,
Bool(bool),
Int(Int),
F32(f32),
F64(f64),
Str(Str),
Bin(Bin),
Array(u32),
Map(u32),
Ext(Ext),
}
impl Token {
#[doc(hidden)]
pub fn to_bool(self) -> Option<bool> {
match self {
Token::Bool(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_int(self) -> Option<Int> {
match self {
Token::Int(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_f32(self) -> Option<f32> {
match self {
Token::F32(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_f64(self) -> Option<f64> {
match self {
Token::F64(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_str(self) -> Option<Str> {
match self {
Token::Str(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_bin(self) -> Option<Bin> {
match self {
Token::Bin(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_array(self) -> Option<u32> {
match self {
Token::Array(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_map(self) -> Option<u32> {
match self {
Token::Map(v) => Some(v),
_ => None,
}
}
#[doc(hidden)]
pub fn to_ext(self) -> Option<Ext> {
match self {
Token::Ext(v) => Some(v),
_ => None,
}
}
}
#[derive(Debug, Error)]
#[error("invalid input")]
pub struct InvalidInputError;
trait ReadExt: ReadBytesExt {
fn read_to_vec(&mut self, len: usize) -> Result<Vec<u8>, io::Error> {
let mut buf = vec![];
buf.resize(len, 0);
self.read_exact(&mut buf)?;
Ok(buf)
}
}
impl<R: io::Read> ReadExt for R {}
#[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.into())?
{
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.into())?,
)),
rmp::Marker::U16 => Token::Int(Int::from(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::U32 => Token::Int(Int::from(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::U64 => Token::Int(Int::from(
self.r
.read_u64::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::I8 => Token::Int(Int::from(
self.r.read_i8().map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::I16 => Token::Int(Int::from(
self.r
.read_i16::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::I32 => Token::Int(Int::from(
self.r
.read_i32::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::I64 => Token::Int(Int::from(
self.r
.read_i64::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
)),
rmp::Marker::F32 => Token::F32(
self.r
.read_f32::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
),
rmp::Marker::F64 => Token::F64(
self.r
.read_f64::<BigEndian>()
.map_err(|_| InvalidInputError.into())?,
),
rmp::Marker::FixStr(len) => {
let len = len as usize;
Token::Str(Str(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Str8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError.into())? as usize;
Token::Str(Str(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Str16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
Token::Str(Str(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Str32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
Token::Str(Str(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Bin8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError.into())? as usize;
Token::Bin(Bin(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Bin16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
Token::Bin(Bin(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::Bin32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
Token::Bin(Bin(self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?))
}
rmp::Marker::FixArray(len) => Token::Array(len as u32),
rmp::Marker::Array16 => Token::Array(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as u32,
),
rmp::Marker::Array32 => Token::Array(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as u32,
),
rmp::Marker::FixMap(len) => Token::Map(len as u32),
rmp::Marker::Map16 => Token::Map(
self.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as u32,
),
rmp::Marker::Map32 => Token::Map(
self.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as u32,
),
rmp::Marker::FixExt1 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(1)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::FixExt2 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(2)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::FixExt4 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(4)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::FixExt8 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(8)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::FixExt16 => {
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(16)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::Ext8 => {
let len = self.r.read_u8().map_err(|_| InvalidInputError.into())? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::Ext16 => {
let len = self
.r
.read_u16::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::Ext32 => {
let len = self
.r
.read_u32::<BigEndian>()
.map_err(|_| InvalidInputError.into())? as usize;
let tag = self.r.read_i8().map_err(|_| InvalidInputError.into())?;
Token::Ext(Ext {
r#type: tag,
data: self
.r
.read_to_vec(len)
.map_err(|_| InvalidInputError.into())?,
})
}
rmp::Marker::Reserved => return Err(InvalidInputError.into()),
};
Ok(token)
}
pub fn deserialize<D: Deserialize>(&mut self) -> Result<D, DeserializeError> {
D::deserialize(self)
}
#[doc(hidden)]
pub fn try_deserialize<D: Deserialize>(&mut self) -> Result<Option<D>, InvalidInputError> {
D::try_deserialize(self)
}
}
#[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>;
#[doc(hidden)]
fn try_deserialize(deserializer: &mut Deserializer) -> Result<Option<Self>, InvalidInputError> {
let mut deserializer2 = deserializer.clone();
match deserializer2.deserialize() {
Ok(v) => {
*deserializer = deserializer2;
Ok(Some(v))
}
Err(DeserializeError::Validation(_)) => Ok(None),
Err(DeserializeError::InvalidInput(err)) => Err(err.into()),
}
}
}
impl Deserialize for bool {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let v = deserializer
.deserialize_token()?
.to_bool()
.ok_or(ValidationError)?;
Ok(v)
}
}
impl Deserialize for Int {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let v = deserializer
.deserialize_token()?
.to_int()
.ok_or(ValidationError)?;
Ok(v)
}
}
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> {
deserializer
.deserialize_token()?
.to_f32()
.ok_or(ValidationError.into())
}
}
impl Deserialize for f64 {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
deserializer
.deserialize_token()?
.to_f64()
.ok_or(ValidationError.into())
}
}
impl Deserialize for Str {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let buf = deserializer
.deserialize_token()?
.to_str()
.ok_or(ValidationError)?;
Ok(buf)
}
}
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 Option<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
if let Some(_) = deserializer.try_deserialize::<Nil>()? {
return Ok(None);
}
let v = deserializer.deserialize()?;
Ok(Some(v))
}
}
impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize(deserializer: &mut Deserializer) -> Result<Self, DeserializeError> {
let len = deserializer
.deserialize_token()?
.to_array()
.ok_or(ValidationError)?;
let mut vec = Vec::with_capacity(len as usize);
for _ in 0..len {
vec.push(deserializer.deserialize()?);
}
Ok(vec.into())
}
}
pub fn serialize<S: Serialize>(s: S) -> Vec<u8> {
let mut serializer = Serializer::new();
serializer.serialize(s);
serializer.into_inner()
}
pub fn deserialize<D: Deserialize>(r: &[u8]) -> Result<D, DeserializeError> {
let mut deserializer = Deserializer::new(r);
deserializer.deserialize()
}
#[doc(hidden)]
#[macro_export]
macro_rules! msgpack {
( $( $tt: tt )+ ) => {
$crate::msgpack_value!($( $tt )+)
};
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, PartialEq, Eq)]
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 = deserializer
.deserialize_token()?
.to_map()
.ok_or(ValidationError)?;
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()?);
}
_ => {
let value::Any = deserializer.deserialize()?;
}
}
}
Ok(Self {
age: age.ok_or(ValidationError)?,
name: name.ok_or(ValidationError)?,
})
}
}
#[test]
fn it_works() {
let val = Human {
age: 42,
name: "John".into(),
};
assert_eq!(val, value::deserialize(value::serialize(&val)).unwrap())
}
#[test]
fn msgpack_macro() {
let val = Human {
age: 42,
name: "John".into(),
};
let buf1 = serialize(&val);
let lit = msgpack!({
0: 42,
1: "John",
});
let buf2 = serialize(&lit);
assert_eq!(buf1, buf2);
}
}