use std::io::Write;
use stream::{Result, Stream};
pub fn to_vec<T : Serialize>(t: T) -> Result<Vec<u8>> {
let mut stream = Stream::new(Vec::new());
t.serialize_body(&mut stream)?;
stream.commit()?;
Ok(stream.into_inner())
}
pub fn to_writer<T : Serialize, W : Write>(writer: W, t: T)
-> Result<()> {
let mut stream = Stream::new(writer);
t.serialize_body(&mut stream)?;
stream.commit()?;
Ok(())
}
pub fn to_stream<T : Serialize, R : Write>(stream: &mut Stream<R>,
t: T)
-> Result<()> {
t.serialize_body(stream)?;
stream.commit()?;
Ok(())
}
pub trait Serialize {
fn serialize_body<R : Write>(&self, dst: &mut Stream<R>)
-> Result<()> {
self.serialize_field(dst, 1)?;
dst.write_end_struct()
}
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
self.serialize_element(dst, tag)
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()>;
#[allow(unused_variables)]
fn serialize_slice<R : Write>
(selves: &[Self], dst: &mut Stream<R>, tag: u8)
-> Option<Result<()>>
where Self : Sized {
None
}
}
pub trait SerializeAs {
type T : Serialize + ?Sized;
fn serialize_as(&self) -> &Self::T;
}
impl<T : SerializeAs + ?Sized> Serialize for T {
fn serialize_body<R : Write>(&self, dst: &mut Stream<R>)
-> Result<()> {
self.serialize_as().serialize_body(dst)
}
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
self.serialize_as().serialize_field(dst, tag)
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
self.serialize_as().serialize_element(dst, tag)
}
}
impl Serialize for () {
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_struct(tag)?;
dst.write_end_struct()
}
}
impl<T : ?Sized> Serialize for ::std::marker::PhantomData<T> {
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_null(tag)
}
}
impl<'a, T : 'a + ?Sized + Serialize> SerializeAs for &'a T {
type T = T;
fn serialize_as(&self) -> &T { *self }
}
impl<'a, T : 'a + ?Sized + Serialize> SerializeAs for &'a mut T {
type T = T;
fn serialize_as(&self) -> &T { *self }
}
impl<T : ?Sized + Serialize> SerializeAs for Box<T> {
type T = T;
fn serialize_as(&self) -> &T { &*self }
}
impl<T : ?Sized + Serialize> SerializeAs for ::std::rc::Rc<T> {
type T = T;
fn serialize_as(&self) -> &T { &*self }
}
impl<T : ?Sized + Serialize> SerializeAs for ::std::sync::Arc<T> {
type T = T;
fn serialize_as(&self) -> &T { &*self }
}
impl<'a, T : ?Sized + Serialize + ToOwned> SerializeAs
for ::std::borrow::Cow<'a, T> {
type T = T;
fn serialize_as(&self) -> &T { &*self }
}
impl<T : Serialize> SerializeAs for Vec<T> {
type T = [T];
fn serialize_as(&self) -> &[T] { &self[..] }
}
impl Serialize for u8 {
fn serialize_element<R : Write>
(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()>
{
dst.write_u8(tag, *self)
}
fn serialize_slice<R : Write>
(selves: &[u8], dst: &mut Stream<R>, tag: u8)
-> Option<Result<()>>
{
Some(dst.write_blob_data(tag, selves).map(|_| ()))
}
}
macro_rules! ser_direct {
($ty:ty, $meth:ident) => {
impl Serialize for $ty {
fn serialize_element<R : Write>
(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()>
{
dst.$meth(tag, *self)
}
}
}
}
ser_direct!(bool, write_bool);
ser_direct!(i8, write_i8);
ser_direct!(u16, write_u16);
ser_direct!(i16, write_i16);
ser_direct!(u32, write_u32);
ser_direct!(i32, write_i32);
ser_direct!(u64, write_u64);
ser_direct!(i64, write_i64);
ser_direct!(usize, write_usize);
ser_direct!(isize, write_isize);
impl Serialize for char {
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_u32(tag, *self as u32)
}
}
macro_rules! ser_bytes {
($($stuff:tt)*) => {
impl $($stuff)* {
fn serialize_element<R : Write>
(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()>
{
let data = AsRef::<[u8]>::as_ref(self);
dst.write_blob_data(tag, data)?;
Ok(())
}
}
}
}
ser_bytes!(Serialize for String);
ser_bytes!(Serialize for str);
macro_rules! ser_array {
($n:tt) => {
impl<T> SerializeAs for [T;$n] where [T]: Serialize {
type T = [T];
fn serialize_as(&self) -> &[T] {
&self[..]
}
}
}
}
ser_array!(0);
ser_array!(1);
ser_array!(2);
ser_array!(3);
ser_array!(4);
ser_array!(5);
ser_array!(6);
ser_array!(7);
ser_array!(8);
ser_array!(9);
ser_array!(10);
ser_array!(11);
ser_array!(12);
ser_array!(13);
ser_array!(14);
ser_array!(15);
ser_array!(16);
ser_array!(17);
ser_array!(18);
ser_array!(19);
ser_array!(20);
ser_array!(21);
ser_array!(22);
ser_array!(23);
ser_array!(24);
ser_array!(25);
ser_array!(26);
ser_array!(27);
ser_array!(28);
ser_array!(29);
ser_array!(30);
ser_array!(31);
ser_array!(32);
ser_array!(64);
ser_array!(128);
ser_array!(256);
ser_array!(512);
ser_array!(1024);
ser_array!(2048);
ser_array!(4096);
ser_array!(8192);
ser_array!(16384);
ser_array!(32768);
ser_array!(65536);
ser_array!(131072);
ser_array!(262144);
ser_array!(524288);
ser_array!(1048576);
ser_array!(2097152);
ser_array!(4194304);
ser_array!(8388608);
ser_array!(16777216);
macro_rules! ser_tuple {
($($t:ident : $v:tt),*) => {
impl <$($t : Serialize),*> Serialize for ($($t,)*) {
fn serialize_body<R : Write>
(&self, dst: &mut Stream<R>) -> Result<()>
{
$(self.$v.serialize_field(dst, $v + 1)?;)*
dst.write_end_struct()
}
fn serialize_element<R : Write>
(&self, dst: &mut Stream<R>, tag: u8) -> Result<()>
{
dst.write_struct(tag)?;
self.serialize_body(dst)
}
}
}
}
ser_tuple!(F0 : 0);
ser_tuple!(F0 : 0, F1 : 1);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10, F11 : 11);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10, F11 : 11, F12 : 12);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10, F11 : 11, F12 : 12, F13 : 13);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10, F11 : 11, F12 : 12, F13 : 13,
F14 : 14);
ser_tuple!(F0 : 0, F1 : 1, F2 : 2, F3 : 3, F4 : 4, F5 : 5, F6 : 6,
F7 : 7, F8 : 8, F9 : 9, F10 : 10, F11 : 11, F12 : 12, F13 : 13,
F14 : 14, F15 : 15);
impl <T : Serialize> Serialize for [T] {
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
if let Some(handled) = T::serialize_slice(self, dst, tag) {
return handled;
}
for e in self {
e.serialize_element(dst, tag)?;
}
Ok(())
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
if let Some(handled) = T::serialize_slice(self, dst, tag) {
return handled;
}
dst.write_struct(tag)?;
self.serialize_field(dst, 1)?;
dst.write_end_struct()
}
}
macro_rules! ser_iter_mut {
($($stuff:tt)*) => {
impl $($stuff)* {
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
for e in self {
e.serialize_element(dst, tag)?;
}
Ok(())
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_struct(tag)?;
self.serialize_field(dst, 1)?;
dst.write_end_struct()
}
}
}
}
ser_iter_mut!(<T : Serialize> Serialize for ::std::collections::LinkedList<T>);
ser_iter_mut!(<T : Serialize> Serialize for ::std::collections::VecDeque<T>);
ser_iter_mut!(<T : Serialize> Serialize for Option<T>);
macro_rules! ser_iter {
($($stuff:tt)*) => {
impl $($stuff)* {
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
for e in self.iter() {
e.serialize_element(dst, tag)?;
}
Ok(())
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_struct(tag)?;
self.serialize_field(dst, 1)?;
dst.write_end_struct()
}
}
}
}
ser_iter!(<T : Serialize + ::std::cmp::Ord> Serialize
for ::std::collections::BTreeSet<T>);
ser_iter!(<T : Serialize + ::std::cmp::Eq + ::std::hash::Hash,
H : ::std::hash::BuildHasher> Serialize
for ::std::collections::HashSet<T, H>);
ser_iter!(<T : Serialize + ::std::cmp::Ord> Serialize
for ::std::collections::BinaryHeap<T>);
macro_rules! ser_map {
($($stuff:tt)*) => {
impl $($stuff)* {
fn serialize_field<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
for (k, v) in self.iter() {
dst.write_struct(tag)?;
k.serialize_field(dst, 1)?;
v.serialize_field(dst, 2)?;
dst.write_end_struct()?;
}
Ok(())
}
fn serialize_element<R : Write>(&self, dst: &mut Stream<R>, tag: u8)
-> Result<()> {
dst.write_struct(tag)?;
self.serialize_field(dst, 1)?;
dst.write_end_struct()
}
}
}
}
ser_map!(<K : Serialize + ::std::cmp::Ord, V : Serialize> Serialize
for ::std::collections::BTreeMap<K, V>);
ser_map!(<K : Serialize + ::std::hash::Hash + ::std::cmp::Eq,
V : Serialize,
H : ::std::hash::BuildHasher> Serialize
for ::std::collections::HashMap<K, V, H>);