use std::convert::From;
use std::io;
use std::io::Write;
use std::result::Result;
use byteorder;
use byteorder::WriteBytesExt;
use super::Marker;
#[derive(Debug)]
pub struct WriteError(io::Error);
impl From<byteorder::Error> for WriteError {
fn from(err: byteorder::Error) -> WriteError {
match err {
byteorder::Error::UnexpectedEOF => {
WriteError(io::Error::new(io::ErrorKind::Other, "unexpected EOF"))
},
byteorder::Error::Io(err) => WriteError(err),
}
}
}
#[derive(Debug)]
pub struct MarkerWriteError(WriteError);
impl From<byteorder::Error> for MarkerWriteError {
fn from(err: byteorder::Error) -> MarkerWriteError {
MarkerWriteError(From::from(err))
}
}
#[derive(Debug)]
pub struct FixedValueWriteError(WriteError);
#[derive(Debug)]
pub enum ValueWriteError {
InvalidMarkerWrite(WriteError),
InvalidDataWrite(WriteError),
}
impl From<MarkerWriteError> for ValueWriteError {
fn from(err: MarkerWriteError) -> ValueWriteError {
match err {
MarkerWriteError(err) => ValueWriteError::InvalidMarkerWrite(err),
}
}
}
impl From<FixedValueWriteError> for ValueWriteError {
fn from(err: FixedValueWriteError) -> ValueWriteError {
match err {
FixedValueWriteError(err) => ValueWriteError::InvalidMarkerWrite(err),
}
}
}
fn write_marker<W>(wr: &mut W, marker: Marker) -> Result<(), MarkerWriteError>
where W: Write
{
wr.write_u8(marker.to_u8()).map_err(From::from)
}
fn write_fixval<W>(wr: &mut W, marker: Marker) -> Result<(), FixedValueWriteError>
where W: Write
{
wr.write_u8(marker.to_u8()).map_err(|err| FixedValueWriteError(From::from(err)))
}
pub fn write_nil<W>(wr: &mut W) -> Result<(), FixedValueWriteError>
where W: Write
{
write_fixval(wr, Marker::Null)
}
pub fn write_bool<W>(wr: &mut W, val: bool) -> Result<(), FixedValueWriteError>
where W: Write
{
match val {
true => write_fixval(wr, Marker::True),
false => write_fixval(wr, Marker::False)
}
}
pub fn write_pfix<W>(wr: &mut W, val: u8) -> Result<(), FixedValueWriteError>
where W: Write
{
assert!(val < 128);
write_fixval(wr, Marker::PositiveFixnum(val))
}
pub fn write_nfix<W>(wr: &mut W, val: i8) -> Result<(), FixedValueWriteError>
where W: Write
{
assert!(-32 <= val && val < 0);
write_fixval(wr, Marker::NegativeFixnum(val))
}
macro_rules! make_write_data_fn {
(deduce, $writer:ident, $encoder:ident, 0, $val:ident)
=> ($writer.$encoder($val););
(deduce, $writer:ident, $encoder:ident, 1, $val:ident)
=> ($writer.$encoder::<byteorder::BigEndian>($val););
(gen, $t:ty, $d:tt, $name:ident, $encoder:ident) => {
fn $name<W>(wr: &mut W, val: $t) -> Result<(), ValueWriteError>
where W: Write
{
match make_write_data_fn!(deduce, wr, $encoder, $d, val) {
Ok(data) => Ok(data),
Err(err) => Err(ValueWriteError::InvalidDataWrite(From::from(err))),
}
}
};
(u8, $name:ident, $encoder:ident) => (make_write_data_fn!(gen, u8, 0, $name, $encoder););
(i8, $name:ident, $encoder:ident) => (make_write_data_fn!(gen, i8, 0, $name, $encoder););
($t:ty, $name:ident, $encoder:ident) => (make_write_data_fn!(gen, $t, 1, $name, $encoder););
}
make_write_data_fn!(u8, write_data_u8, write_u8);
make_write_data_fn!(u16, write_data_u16, write_u16);
make_write_data_fn!(u32, write_data_u32, write_u32);
make_write_data_fn!(u64, write_data_u64, write_u64);
make_write_data_fn!(i8, write_data_i8, write_i8);
make_write_data_fn!(i16, write_data_i16, write_i16);
make_write_data_fn!(i32, write_data_i32, write_i32);
make_write_data_fn!(i64, write_data_i64, write_i64);
make_write_data_fn!(f32, write_data_f32, write_f32);
make_write_data_fn!(f64, write_data_f64, write_f64);
pub fn write_u8<W>(wr: &mut W, val: u8) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::U8));
write_data_u8(wr, val)
}
pub fn write_u16<W>(wr: &mut W, val: u16) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::U16));
write_data_u16(wr, val)
}
pub fn write_u32<W>(wr: &mut W, val: u32) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::U32));
write_data_u32(wr, val)
}
pub fn write_u64<W>(wr: &mut W, val: u64) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::U64));
write_data_u64(wr, val)
}
pub fn write_i8<W>(wr: &mut W, val: i8) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::I8));
write_data_i8(wr, val)
}
pub fn write_i16<W>(wr: &mut W, val: i16) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::I16));
write_data_i16(wr, val)
}
pub fn write_i32<W>(wr: &mut W, val: i32) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::I32));
write_data_i32(wr, val)
}
pub fn write_i64<W>(wr: &mut W, val: i64) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::I64));
write_data_i64(wr, val)
}
pub fn write_uint<W>(wr: &mut W, val: u64) -> Result<Marker, ValueWriteError>
where W: Write
{
if val < 128 {
let marker = Marker::PositiveFixnum(val as u8);
try!(write_fixval(wr, marker));
Ok(marker)
} else if val < 256 {
write_u8(wr, val as u8).and(Ok(Marker::U8))
} else if val < 65536 {
write_u16(wr, val as u16).and(Ok(Marker::U16))
} else if val < 4294967296 {
write_u32(wr, val as u32).and(Ok(Marker::U32))
} else {
write_u64(wr, val).and(Ok(Marker::U64))
}
}
pub fn write_sint<W>(wr: &mut W, val: i64) -> Result<Marker, ValueWriteError>
where W: Write
{
if -32 <= val && val <= 0 {
let marker = Marker::NegativeFixnum(val as i8);
try!(write_fixval(wr, marker));
Ok(marker)
} else if -128 <= val && val < 128 {
write_i8(wr, val as i8).and(Ok(Marker::I8))
} else if -32768 <= val && val < 32768 {
write_i16(wr, val as i16).and(Ok(Marker::I16))
} else if -2147483648 <= val && val <= 2147483647 {
write_i32(wr, val as i32).and(Ok(Marker::I32))
} else {
write_i64(wr, val).and(Ok(Marker::I64))
}
}
#[allow(dead_code, unused_variables)]
fn write_int<W>(wr: &mut W, val: i64) -> Result<Marker, ValueWriteError>
where W: Write
{
unimplemented!()
}
pub fn write_f32<W>(wr: &mut W, val: f32) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::F32));
write_data_f32(wr, val)
}
pub fn write_f64<W>(wr: &mut W, val: f64) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_marker(wr, Marker::F64));
write_data_f64(wr, val)
}
pub fn write_str_len<W>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError>
where W: Write
{
if len < 32 {
let marker = Marker::FixedString(len as u8);
try!(write_fixval(wr, marker));
Ok(marker)
} else if len < 256 {
try!(write_marker(wr, Marker::Str8));
write_data_u8(wr, len as u8).and(Ok(Marker::Str8))
} else if len < 65536 {
try!(write_marker(wr, Marker::Str16));
write_data_u16(wr, len as u16).and(Ok(Marker::Str16))
} else {
try!(write_marker(wr, Marker::Str32));
write_data_u32(wr, len).and(Ok(Marker::Str32))
}
}
fn write_str<W>(wr: &mut W, data: &str) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_str_len(wr, data.len() as u32));
wr.write_all(data.as_bytes()).map_err(|err| ValueWriteError::InvalidDataWrite(WriteError(err)))
}
pub fn write_bin_len<W>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError>
where W: Write
{
if len < 256 {
try!(write_marker(wr, Marker::Bin8));
write_data_u8(wr, len as u8).and(Ok(Marker::Bin8))
} else if len < 65536 {
try!(write_marker(wr, Marker::Bin16));
write_data_u16(wr, len as u16).and(Ok(Marker::Bin16))
} else {
try!(write_marker(wr, Marker::Bin32));
write_data_u32(wr, len).and(Ok(Marker::Bin32))
}
}
fn write_bin<W>(wr: &mut W, data: &[u8]) -> Result<(), ValueWriteError>
where W: Write
{
try!(write_bin_len(wr, data.len() as u32));
wr.write_all(data).map_err(|err| ValueWriteError::InvalidDataWrite(WriteError(err)))
}
pub fn write_array_len<W>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError>
where W: Write
{
if len < 16 {
let marker = Marker::FixedArray(len as u8);
try!(write_fixval(wr, marker));
Ok(marker)
} else if len < 65536 {
try!(write_marker(wr, Marker::Array16));
write_data_u16(wr, len as u16).and(Ok(Marker::Array16))
} else {
try!(write_marker(wr, Marker::Array32));
write_data_u32(wr, len).and(Ok(Marker::Array32))
}
}
pub fn write_map_len<W>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError>
where W: Write
{
if len < 16 {
let marker = Marker::FixedMap(len as u8);
try!(write_fixval(wr, marker));
Ok(marker)
} else if len < 65536 {
try!(write_marker(wr, Marker::Map16));
write_data_u16(wr, len as u16).and(Ok(Marker::Map16))
} else {
try!(write_marker(wr, Marker::Map32));
write_data_u32(wr, len).and(Ok(Marker::Map32))
}
}
pub fn write_ext_meta<W>(wr: &mut W, len: u32, typeid: i8) -> Result<Marker, ValueWriteError>
where W: Write
{
assert!(typeid >= 0);
let marker = match len {
1 => {
try!(write_marker(wr, Marker::FixExt1));
Marker::FixExt1
}
2 => {
try!(write_marker(wr, Marker::FixExt2));
Marker::FixExt2
}
4 => {
try!(write_marker(wr, Marker::FixExt4));
Marker::FixExt4
}
8 => {
try!(write_marker(wr, Marker::FixExt8));
Marker::FixExt8
}
16 => {
try!(write_marker(wr, Marker::FixExt16));
Marker::FixExt16
}
len if len < 256 => {
try!(write_marker(wr, Marker::Ext8));
try!(write_data_u8(wr, len as u8));
Marker::Ext8
}
len if len < 65536 => {
try!(write_marker(wr, Marker::Ext16));
try!(write_data_u16(wr, len as u16));
Marker::Ext16
}
len => {
try!(write_marker(wr, Marker::Ext32));
try!(write_data_u32(wr, len));
Marker::Ext32
}
};
try!(write_data_i8(wr, typeid));
Ok(marker)
}
pub mod value {
use std::convert::From;
use std::io::Write;
use std::result::Result;
pub use super::super::value::{
Integer,
Float,
Value,
};
use super::*;
use super::{write_str, write_bin};
#[derive(Debug)]
pub enum Error {
UnstableCommonError(String),
}
impl From<FixedValueWriteError> for Error {
fn from(err: FixedValueWriteError) -> Error {
match err {
FixedValueWriteError(..) => Error::UnstableCommonError("fixed value error".to_string())
}
}
}
impl From<ValueWriteError> for Error {
fn from(_: ValueWriteError) -> Error {
Error::UnstableCommonError("value error".to_string())
}
}
pub fn write_value<W>(wr: &mut W, val: &Value) -> Result<(), Error>
where W: Write
{
match val {
&Value::Nil => try!(write_nil(wr)),
&Value::Boolean(val) => try!(write_bool(wr, val)),
&Value::Integer(Integer::U64(val)) => {
try!(write_uint(wr, val));
}
&Value::Integer(Integer::I64(val)) => {
try!(write_sint(wr, val));
}
&Value::Float(Float::F32(val)) => try!(write_f32(wr, val)),
&Value::Float(Float::F64(val)) => try!(write_f64(wr, val)),
&Value::String(ref val) => {
try!(write_str(wr, &val));
}
&Value::Binary(ref val) => {
try!(write_bin(wr, &val));
}
&Value::Array(ref val) => {
try!(write_array_len(wr, val.len() as u32));
for item in val {
try!(write_value(wr, item));
}
}
&Value::Map(ref val) => {
try!(write_map_len(wr, val.len() as u32));
for &(ref key, ref val) in val {
try!(write_value(wr, key));
try!(write_value(wr, val));
}
}
&Value::Ext(ty, ref data) => {
try!(write_ext_meta(wr, data.len() as u32, ty));
try!(wr.write_all(data).map_err(|err| ValueWriteError::InvalidDataWrite(WriteError(err))));
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pack_nil() {
let mut buf = [0x00];
let val = Value::Nil;
write_value(&mut &mut buf[..], &val).unwrap();
assert_eq!([0xc0], buf);
}
}
}
pub mod serialize {
use serialize;
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,
};
use super::{
WriteError,
FixedValueWriteError,
};
#[derive(Debug)]
pub enum Error {
InvalidFixedValueWrite(WriteError),
Unimplemented,
}
impl From<FixedValueWriteError> for Error {
fn from(err: FixedValueWriteError) -> Error {
match err {
FixedValueWriteError(err) => Error::InvalidFixedValueWrite(err)
}
}
}
impl From<super::ValueWriteError> for Error {
fn from(err: super::ValueWriteError) -> Error {
match err {
_ => Error::Unimplemented,
}
}
}
pub struct Encoder<'a> {
wr: &'a mut Write,
}
impl<'a> Encoder<'a> {
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(&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)
}
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)
}
fn emit_enum<F>(&mut self, _name: &str, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
try!(write_array_len(&mut self.wr, 2));
f(self)
}
fn emit_enum_variant<F>(&mut self, _name: &str, id: usize, len: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
try!(self.emit_usize(id));
try!(write_array_len(&mut self.wr, len as u32));
f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_enum_struct_variant<F>(&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<F>(&mut self, _name: &str, _idx: usize, _f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
unimplemented!()
}
fn emit_struct<F>(&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<F>(&mut self, _name: &str, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_tuple<F>(&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<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_tuple_struct<F>(&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<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_option<F>(&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<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_seq<F>(&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<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_map<F>(&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<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Self) -> Result<(), Error>
{
f(self)
}
}
}