bytevec 0.1.1

A Rust serialization library that uses byte vectors
Documentation
use traits::{ByteEncodable, ByteDecodable};
use errors::{ByteVecError, BVWantedSize};
use std::mem::transmute;
use {BVEncodeResult, BVDecodeResult};
use std::mem::size_of;

macro_rules! impl_integrals {
    {$($t:ty : $size:expr),*} => {
        $(
            impl ByteEncodable for $t {
                fn get_size(&self) -> Option<u32> {
                    Some($size)
                }

                fn encode(&self) -> BVEncodeResult<Vec<u8>> {
                    unsafe {
                        let bytes: [u8; $size] = transmute(self.to_be());
                        Ok(bytes.to_vec())
                    }
                }
            }

            impl ByteDecodable for $t {
                fn decode(bytes: &[u8]) -> BVDecodeResult<$t> {
                    if bytes.len() == $size {
                        let mut t_bytes = [0u8; $size];
                        for (b, s) in (&mut t_bytes).into_iter().zip(bytes) {
                            *b = *s;
                        }
                        unsafe { Ok(<$t>::from_be(transmute(t_bytes))) }
                    } else {
                        Err(ByteVecError::BadSizeDecodeError {
                            wanted: BVWantedSize::EqualTo($size),
                            actual: bytes.len() as u32
                        })
                    }
                }
            }
        )*
    }
}

impl_integrals! {
    u8: 1,
    u16: 2,
    u32: 4,
    u64: 8,
    i8: 1,
    i16: 2,
    i32: 4,
    i64: 8
}

macro_rules! as_unsized_impl {
    {$($t:ty : $unsizd:ty),*} => {
        $(
            impl ByteEncodable for $t {
                fn get_size(&self) -> Option<u32> {
                    Some(size_of::<$t>() as u32)
                }

                fn encode(&self) -> BVEncodeResult<Vec<u8>> {
                    unsafe {
                        let unsigned: $unsizd = transmute(*self);
                        unsigned.encode()
                    }
                }
            }

            impl ByteDecodable for $t {
                fn decode(bytes: &[u8]) -> BVDecodeResult<$t> {
                    let unsigned = try!(<$unsizd>::decode(bytes));
                    unsafe { Ok(transmute(unsigned)) }
                }
            }
        )*
    }
}

as_unsized_impl! {
    f32: u32,
    f64: u64,
    char: u32
}

impl ByteEncodable for usize {
    fn get_size(&self) -> Option<u32> {
        Some(size_of::<usize>() as u32)
    }

    fn encode(&self) -> BVEncodeResult<Vec<u8>> {
        match size_of::<usize>() {
            2 => (*self as u16).encode(),
            4 => (*self as u32).encode(),
            8 => (*self as u64).encode(),
            _ => panic!("unknown size for usize"),
        }
    }
}

impl ByteDecodable for usize {
    fn decode(bytes: &[u8]) -> BVDecodeResult<usize> {
        Ok(match size_of::<usize>() {
            2 => try!(u16::decode(bytes)) as usize,
            4 => try!(u32::decode(bytes)) as usize,
            8 => try!(u64::decode(bytes)) as usize,
            _ => panic!("unknown size for usize"),
        })
    }
}