use std::io::Write;
use std::marker::PhantomData;
use byteorder::{ByteOrder, WriteBytesExt};
use serde::ser::{self, Serialize};
use error::{Error, Result};
pub struct Serializer<BO, W> {
writer: W,
_byteorder: PhantomData<BO>,
}
impl<BO, W> Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
pub fn new(writer: W) -> Self {
Serializer { writer, _byteorder: PhantomData }
}
}
impl<'a, BO, W> ser::Serializer for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_i8 (self, v: i8 ) -> Result<Self::Ok> { self.writer.write_i8(v).map_err(Into::into) }
fn serialize_u8 (self, v: u8 ) -> Result<Self::Ok> { self.writer.write_u8(v).map_err(Into::into) }
fn serialize_i16(self, v: i16) -> Result<Self::Ok> { self.writer.write_i16::<BO>(v).map_err(Into::into) }
fn serialize_u16(self, v: u16) -> Result<Self::Ok> { self.writer.write_u16::<BO>(v).map_err(Into::into) }
fn serialize_i32(self, v: i32) -> Result<Self::Ok> { self.writer.write_i32::<BO>(v).map_err(Into::into) }
fn serialize_u32(self, v: u32) -> Result<Self::Ok> { self.writer.write_u32::<BO>(v).map_err(Into::into) }
fn serialize_i64(self, v: i64) -> Result<Self::Ok> { self.writer.write_i64::<BO>(v).map_err(Into::into) }
fn serialize_u64(self, v: u64) -> Result<Self::Ok> { self.writer.write_u64::<BO>(v).map_err(Into::into) }
fn serialize_i128(self, v: i128) -> Result<Self::Ok> { self.writer.write_i128::<BO>(v).map_err(Into::into) }
fn serialize_u128(self, v: u128) -> Result<Self::Ok> { self.writer.write_u128::<BO>(v).map_err(Into::into) }
fn serialize_f32(self, v: f32) -> Result<Self::Ok> { self.writer.write_f32::<BO>(v).map_err(Into::into) }
fn serialize_f64(self, v: f64) -> Result<Self::Ok> { self.writer.write_f64::<BO>(v).map_err(Into::into) }
fn serialize_bool(self, v: bool) -> Result<Self::Ok> { self.serialize_u8(if v { 1 } else { 0 }) }
#[inline]
fn serialize_char(self, v: char) -> Result<Self::Ok> {
let mut buf = [0u8; 4];
self.serialize_str(v.encode_utf8(&mut buf))
}
#[inline]
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
self.serialize_bytes(v.as_bytes())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> { self.writer.write_all(v).map_err(Into::into) }
fn serialize_none(self) -> Result<Self::Ok> { Ok(()) }
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok> { Ok(()) }
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> { Ok(()) }
fn serialize_unit_variant(
self, _name: &'static str, _variant_index: u32, _variant: &'static str
) -> Result<Self::Ok> { Ok(()) }
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self, _name: &'static str, _variant_index: u32, _variant: &'static str, value: &T
) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { Ok(self) }
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { Ok(self) }
fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> { Ok(self) }
fn serialize_tuple_variant(
self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize
) -> Result<Self::SerializeTupleVariant> { Ok(self) }
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { Ok(self) }
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { Ok(self) }
fn serialize_struct_variant(
self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize
) -> Result<Self::SerializeStructVariant> { Ok(self) }
fn is_human_readable(&self) -> bool { false }
}
impl<'a, BO, W> ser::SerializeSeq for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeTuple for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeTupleStruct for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeTupleVariant for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeMap for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
key.serialize(&mut **self)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeStruct for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
impl<'a, BO, W> ser::SerializeStructVariant for &'a mut Serializer<BO, W>
where W: Write,
BO: ByteOrder,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<Self::Ok>
where T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok> { Ok(()) }
}
#[inline]
pub fn to_writer<BO, W, T>(writer: W, value: &T) -> Result<()>
where BO: ByteOrder,
W: Write,
T: ?Sized + Serialize,
{
let mut ser: Serializer<BO, W> = Serializer::new(writer);
value.serialize(&mut ser)
}
#[inline]
pub fn to_vec<BO, T>(value: &T) -> Result<Vec<u8>>
where BO: ByteOrder,
T: ?Sized + Serialize,
{
let mut vec = Vec::new();
to_writer::<BO, _, _>(&mut vec, value)?;
Ok(vec)
}
#[cfg(test)]
mod integers {
use super::to_vec;
use byteorder::{BE, LE};
#[test]
fn test_u8() {
let test: u8 = 0x12;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x12]);
}
#[test]
fn test_i8() {
let test: i8 = 0x12;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x12]);
}
#[test]
fn test_u16() {
let test: u16 = 0x1234;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x34, 0x12]);
}
#[test]
fn test_i16() {
let test: i16 = 0x1234;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x34, 0x12]);
}
#[test]
fn test_u32() {
let test: u32 = 0x12345678;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_i32() {
let test: i32 = 0x12345678;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_u64() {
let test: u64 = 0x12345678_90ABCDEF;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_i64() {
let test: i64 = 0x12345678_90ABCDEF;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_u128() {
let test: u128 = 0x12345678_90ABCDEF_12345678_90ABCDEF;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_i128() {
let test: i128 = 0x12345678_90ABCDEF_12345678_90ABCDEF;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), vec![0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
}
}
#[cfg(test)]
mod floats {
use super::to_vec;
use byteorder::{ByteOrder, BE, LE};
macro_rules! float_test {
($name:ident, $BO:ident :: $write:ident, $type:ty) => (
quickcheck! {
fn $name(test: $type) -> bool {
let mut buf = [0; std::mem::size_of::<$type>()];
$BO::$write(&mut buf, test);
to_vec::<$BO,_>(&test).unwrap() == buf
}
}
);
}
float_test!(test_f32_be, BE::write_f32, f32);
float_test!(test_f32_le, LE::write_f32, f32);
float_test!(test_f64_be, BE::write_f64, f64);
float_test!(test_f64_le, LE::write_f64, f64);
}
#[cfg(test)]
mod complex {
use super::to_vec;
use byteorder::{BE, LE};
quickcheck! {
fn test_bool_be(test: bool) -> bool {
let result = [if test { 1u8 } else { 0u8 }];
to_vec::<BE, _>(&test).unwrap() == result
}
fn test_bool_le(test: bool) -> bool {
let result = [if test { 1u8 } else { 0u8 }];
to_vec::<LE, _>(&test).unwrap() == result
}
}
#[test]
fn test_unit() {
#[derive(Serialize)]
struct Test;
let test = Test;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), []);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), []);
}
#[test]
fn test_newtype() {
#[derive(Serialize)]
struct Test(u32);
let test = Test(0x12345678);
assert_eq!(to_vec::<BE,_>(&test).unwrap(), [0x12, 0x34, 0x56, 0x78]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), [0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_tuple() {
#[derive(Serialize)]
struct Test(u32, u16);
let test = Test(0x12345678, 0xABCD);
assert_eq!(to_vec::<BE,_>(&test).unwrap(), [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), [0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB]);
}
#[test]
fn test_struct() {
#[derive(Serialize)]
struct Test {
int1: u32,
int2: u16,
}
let test = Test { int1: 0x12345678, int2: 0xABCD };
assert_eq!(to_vec::<BE,_>(&test).unwrap(), [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), [0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB]);
}
#[test]
fn test_option_some() {
let test = Some(0x12345678_u32);
assert_eq!(to_vec::<BE,_>(&test).unwrap(), [0x12, 0x34, 0x56, 0x78]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), [0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_option_none() {
let test: Option<u32> = None;
assert_eq!(to_vec::<BE,_>(&test).unwrap(), []);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), []);
}
#[test]
fn test_seq() {
let test: Vec<u16> = vec![0x1234, 0x5678, 0xABCD];
assert_eq!(to_vec::<BE,_>(&test).unwrap(), [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), [0x34, 0x12, 0x78, 0x56, 0xCD, 0xAB]);
}
#[test]
fn test_str() {
let test = "тест";
assert_eq!(to_vec::<BE,_>(&test).unwrap(), test.as_bytes());
assert_eq!(to_vec::<LE,_>(&test).unwrap(), test.as_bytes());
assert_eq!(to_vec::<BE,_>(&test.to_owned()).unwrap(), test.as_bytes());
assert_eq!(to_vec::<LE,_>(&test.to_owned()).unwrap(), test.as_bytes());
}
#[test]
fn test_array_empty() {
let test: [u8; 0] = [];
assert_eq!(to_vec::<BE,_>(&test).unwrap(), []);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), []);
}
#[test]
fn test_array() {
let test: [u8; 6] = [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD];
assert_eq!(to_vec::<BE,_>(&test).unwrap(), test);
assert_eq!(to_vec::<LE,_>(&test).unwrap(), test);
}
}
#[cfg(test)]
mod enums {
use super::to_vec;
use byteorder::{BE, LE};
#[derive(Serialize)]
enum E {
Unit,
Newtype(u32),
Tuple(u32, u16),
Struct { int1: u32, int2: u16 },
}
#[test]
fn test_enum_unit() {
let u = E::Unit;
assert_eq!(to_vec::<BE,_>(&u).unwrap(), []);
assert_eq!(to_vec::<LE,_>(&u).unwrap(), []);
}
#[test]
fn test_enum_newtype() {
let n = E::Newtype(0x12345678);
assert_eq!(to_vec::<BE,_>(&n).unwrap(), [0x12, 0x34, 0x56, 0x78]);
assert_eq!(to_vec::<LE,_>(&n).unwrap(), [0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_enum_tuple() {
let t = E::Tuple(0x12345678, 0xABCD);
assert_eq!(to_vec::<BE,_>(&t).unwrap(), [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]);
assert_eq!(to_vec::<LE,_>(&t).unwrap(), [0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB]);
}
#[test]
fn test_enum_struct() {
let s = E::Struct { int1: 0x12345678, int2: 0xABCD };
assert_eq!(to_vec::<BE,_>(&s).unwrap(), [0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]);
assert_eq!(to_vec::<LE,_>(&s).unwrap(), [0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB]);
}
}