zero-formatter 0.1.0

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

use std::{i32, usize};
use std::borrow::Cow;
use std::ops::Deref;
use std::string::String;
//use std::convert::TryFrom;
use std::io::{Seek, SeekFrom};
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};

impl<R> Formatter<u8> for R where R: Seek + ReadBytesExt + WriteBytesExt {

    fn serialize(&mut self, offset: u64, value: u8) -> ZeroFormatterResult<i32> {
        try!(self.seek(SeekFrom::Start(offset)));
        try!(self.write_u8(value));
        Ok(1)
    }

    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<u8> {
        try!(self.seek(SeekFrom::Start(*(offset as &u64))));
        let n = try!(self.read_u8());
        *offset += 1;
        Ok(n)
    }
}

impl<R> Formatter<bool> for R where R: Seek + ReadBytesExt + WriteBytesExt {

    fn serialize(&mut self, offset: u64, value: bool) -> ZeroFormatterResult<i32> {
        let i: u8 = if value { 1 } else { 0 };
        self.serialize(offset, i)
    }

    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<bool> {
        let n: u8 = try!(self.deserialize(offset));
        if n == 1 { Ok(true) }
        else if n == 0 { Ok(false) }
        else { ZeroFormatterError::invalid_binary(*offset) }
    }
}

impl<R> Formatter<i8> for R where R: Seek + ReadBytesExt + WriteBytesExt {

    fn serialize(&mut self, offset: u64, value: i8) -> ZeroFormatterResult<i32> {
        try!(self.seek(SeekFrom::Start(offset)));
        try!(self.write_i8(value));
        Ok(1)
    }

    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<i8> {
        try!(self.seek(SeekFrom::Start(*(offset as &u64))));
        let n = try!(self.read_i8());
        *offset += 1;
        Ok(n)
    }
}

macro_rules! primitive_formatter_impl {
    ($($t:ty; $w:tt; $r:tt; $l:expr),*) => ($(
        impl<R> Formatter<$t> for R where R: Seek + ReadBytesExt + WriteBytesExt {

            fn serialize(&mut self, offset: u64, value: $t) -> ZeroFormatterResult<i32> {
                try!(self.seek(SeekFrom::Start(offset)));
                try!(self.$w::<LittleEndian>(value));
                Ok($l)
            }

            fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<$t> {
                try!(self.seek(SeekFrom::Start(*(offset as &u64))));
                let n = try!(self.$r::<LittleEndian>());
                *offset += $l;
                Ok(n)
            }
        }
    )*)
}

primitive_formatter_impl! {
    u16; write_u16; read_u16; 2,
    u32; write_u32; read_u32; 4,
    u64; write_u64; read_u64; 8,
    i16; write_i16; read_i16; 2,
    i32; write_i32; read_i32; 4,
    i64; write_i64; read_i64; 8,
    f32; write_f32; read_f32; 4,
    f64; write_f64; read_f64; 8
}

impl<'a, R> Formatter<Cow<'a, str>> for R where R: Seek + ReadBytesExt + WriteBytesExt {

    fn serialize(&mut self, offset: u64, value: Cow<'a, str>) -> ZeroFormatterResult<i32> {
        let bytes = value.deref().as_bytes();
        let l = bytes.len();
        //let i = try!(i32::try_from(l));
        let i = l as i32;
        try!(self.seek(SeekFrom::Start(offset)));
        try!(self.write_i32::<LittleEndian>(i));
        try!(self.write(bytes));
        Ok(i + 4)
    }

    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<Cow<'a, str>> {
        let i: i32 = try!(util::check_non_null(self, offset));
        //let l = try!(usize::try_from(i));
        let l = i as usize;
        let mut buf = Vec::with_capacity(l);
        unsafe { buf.set_len(l); }
        try!(self.read(&mut buf));
        *offset += l as u64;
        let s = try!(String::from_utf8(buf));
        Ok(s.into())
    }
}

#[cfg(test)]
mod tests {

    use std::io::Cursor;
    use std::borrow::Cow;
    use formatter::*;

    #[test]
    fn serialize_true() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, true).unwrap(), 1);
        assert_eq!(wtr.into_inner(), vec![1]);
    }

    #[test]
    fn deserialize_true() {
        let mut rdr = Cursor::new(vec![1]);
        let mut offset = 0;
        assert_eq!(true, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_false() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, false).unwrap(), 1);
        assert_eq!(wtr.into_inner(), vec![0]);
    }

    #[test]
    fn deserialize_false() {
        let mut rdr = Cursor::new(vec![0]);
        let mut offset = 0;
        assert_eq!(false, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_u8() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1u8).unwrap(), 1);
        assert_eq!(wtr.into_inner(), vec![1]);
    }

    #[test]
    fn deserialize_u8() {
        let mut rdr = Cursor::new(vec![1]);
        let mut offset = 0;
        assert_eq!(1u8, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_u16() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1u16).unwrap(), 2);
        assert_eq!(wtr.into_inner(), vec![1, 0]);
    }

    #[test]
    fn deserialize_u16() {
        let mut rdr = Cursor::new(vec![1, 0]);
        let mut offset = 0;
        assert_eq!(1u16, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_u32() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1u32).unwrap(), 4);
        assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0]);
    }

    #[test]
    fn deserialize_u32() {
        let mut rdr = Cursor::new(vec![1, 0, 0, 0]);
        let mut offset = 0;
        assert_eq!(1u32, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_u64() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1u64).unwrap(), 8);
        assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn deserialize_u64() {
        let mut rdr = Cursor::new(vec![1, 0, 0, 0, 0, 0, 0, 0]);
        let mut offset = 0;
        assert_eq!(1u64, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_i8() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1i8).unwrap(), 1);
        assert_eq!(wtr.into_inner(), vec![1]);
    }

    #[test]
    fn deserialize_i8() {
        let mut rdr = Cursor::new(vec![1]);
        let mut offset = 0;
        assert_eq!(1i8, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_i16() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1i16).unwrap(), 2);
        assert_eq!(wtr.into_inner(), vec![1, 0]);
    }

    #[test]
    fn deserialize_i16() {
        let mut rdr = Cursor::new(vec![1, 0]);
        let mut offset = 0;
        assert_eq!(1i16, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_i32() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1i32).unwrap(), 4);
        assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0]);
    }

    #[test]
    fn deserialize_i32() {
        let mut rdr = Cursor::new(vec![1, 0, 0, 0]);
        let mut offset = 0;
        assert_eq!(1i32, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_i64() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 1i64).unwrap(), 8);
        assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn deserialize_i64() {
        let mut rdr = Cursor::new(vec![1, 0, 0, 0, 0, 0, 0, 0]);
        let mut offset = 0;
        assert_eq!(1i64, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_f32() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 123.0f32).unwrap(), 4);
        assert_eq!(wtr.into_inner(), vec![0, 0, 0xf6, 0x42]);
    }

    #[test]
    fn deserialize_f32() {
        let mut rdr = Cursor::new(vec![0, 0, 0xf6, 0x42]);
        let mut offset = 0;
        assert_eq!(123.0f32, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_f64() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, 123.0f64).unwrap(), 8);
        assert_eq!(wtr.into_inner(), vec![0, 0, 0, 0, 0, 0xc0, 0x5e, 0x40]);
    }

    #[test]
    fn deserialize_f64() {
        let mut rdr = Cursor::new(vec![0, 0, 0, 0, 0, 0xc0, 0x5e, 0x40]);
        let mut offset = 0;
        assert_eq!(123.0f64, rdr.deserialize(&mut offset).unwrap());
    }

    #[test]
    fn serialize_str() {
        let mut wtr = Cursor::new(Vec::new());
        assert_eq!(wtr.serialize(0, Cow::Borrowed("あいうえお")).unwrap(), 19);
        assert_eq!(wtr.into_inner(), vec![0x0f, 0, 0, 0, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a]);
    }

    #[test]
    fn deserialize_str() {
        let mut rdr = Cursor::new(vec![0x0f, 0, 0, 0, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a]);
        let mut offset = 0;
        let actual: Cow<'static, str> = rdr.deserialize(&mut offset).unwrap();
        assert_eq!(offset, 19);
        assert_eq!(Cow::Borrowed("あいうえお"), actual);
    }
}