zero-formatter 0.1.0

ZeroFormatter implementation for Rust
Documentation
use error::*;
use formatter::*;
use util;

use std::io::Seek;
use byteorder::{ReadBytesExt, WriteBytesExt};
use std::borrow::Cow;

fn try_deserialize<R, A>(s: &mut R, n: i32, v: &mut Vec<A>, offset: &mut u64) -> ZeroFormatterResult<()>
    where R: Seek + ReadBytesExt + WriteBytesExt + Formatter<A> {
    if n < 0 {
      Ok(())
    } else {
      let a = try!(s.deserialize(offset));
      v.push(a);
      try_deserialize(s, n - 1, v, offset)
    }
}

impl<'a, R, A: Clone> Formatter<Cow<'a, [A]>> for R
    where R: Seek + ReadBytesExt + WriteBytesExt + Formatter<A> + Formatter<i32> {

    fn serialize(&mut self, offset: u64, value: Cow<'a, [A]>) -> ZeroFormatterResult<i32> {
        let v: Vec<A> = value.into_owned();
        let lr = try!(self.serialize(offset, v.len() as i32));
        let byte_size = try!(v.iter().fold(
            Ok(lr),
            |b, a| {
                b.and_then(|bs| {
                    self.serialize(offset + (bs as u64), a.clone())
                        .map(|s| bs + s)
                })
            }
        ));
        Ok(byte_size as i32)
    }

    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<Cow<'a, [A]>> {
        let l: i32 = try!(util::check_non_null(self, offset));
        let mut v: Vec<A> = Vec::with_capacity(l as usize);
        try!(try_deserialize(self, l - 1, &mut v, offset));
        Ok(Cow::from(v))
    }
}

#[cfg(test)]
mod tests {

    use std::io::Cursor;
    use std::borrow::Cow;
    use std::io::{Seek, SeekFrom};
    use error::*;
    use formatter::*;
    use util;

    #[test]
    fn serialize_vec() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, Cow::from(vec![1i32, 2i32, 3i32])).unwrap(), 16);
        assert_eq!(wtr.into_inner(), vec![3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
    }

    #[test]
    fn deserialize_vec() {
        let mut rdr = Cursor::new(vec![3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
        let mut offset = 0;
        let actual: Cow<'static, [i32]> = rdr.deserialize(&mut offset).unwrap();
        assert_eq!(offset, 16);
        assert_eq!(Cow::from(vec![1, 2, 3]), actual);
    }

    struct_formatter! {
        #[target(Cursor<Vec<u8>>)]
        S {
            a: i32
        }
    }

    #[test]
    fn serialize_vec_struct() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, Cow::from(vec![S{a: 1}, S{a: 2}, S{a: 3}])).unwrap(), 16);
        assert_eq!(wtr.into_inner(), vec![3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
    }

    #[test]
    fn deserialize_vec_struct() {
        let mut rdr = Cursor::new(vec![3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
        let mut offset = 0;
        let actual: Cow<'static, [S]> = rdr.deserialize(&mut offset).unwrap();
        assert_eq!(offset, 16);
        assert_eq!(Cow::from(vec![S{a: 1}, S{a: 2}, S{a: 3}]), actual);
    }

    object_formatter! {
        #[target(Cursor<Vec<u8>>)]
        O {
            0; a: i32
        }
    }

    #[test]
    fn serialize_vec_object() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, Cow::from(vec![O{a: 1}, O{a: 2}, O{a: 3}])).unwrap(), 52);
        let expected = vec![
            3, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            16, 0, 0, 0,
            1, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            32, 0, 0, 0,
            2, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            48, 0, 0, 0,
            3, 0, 0, 0,
        ];
        assert_eq!(wtr.into_inner(), expected);
    }

    #[test]
    fn deserialize_vec_object() {
        let mut rdr = Cursor::new(vec![
            3, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            16, 0, 0, 0,
            1, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            32, 0, 0, 0,
            2, 0, 0, 0,

            16, 0, 0, 0,
            0, 0, 0, 0,
            48, 0, 0, 0,
            3, 0, 0, 0,
        ]);
        let mut offset = 0;
        let actual: Cow<'static, [O]> = rdr.deserialize(&mut offset).unwrap();
        assert_eq!(offset, 52);
        assert_eq!(Cow::from(vec![O{a: 1}, O{a: 2}, O{a: 3}]), actual);
    }
}