1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
use std::io::Result;
pub use byteorder::{ReadBytesExt, WriteBytesExt};
pub type Reader<'a> = &'a [u8];
pub type Writer = Vec<u8>;
/// A type that can be serialized to and from bytes.
/// Should only be implemented on types that own their data, i.e. `String` and not `&str`.
pub trait Io : Sized {
/// Read data from the reader.
fn read(r: &mut Reader) -> Result<Self>;
/// Write this data to the reader.
fn write(&self, w: &mut Writer) -> Result<()>;
/// Number of bytes this data will take up when written
fn size(&self) -> usize;
/// Create a Vec<u8> and write to it.
/// Should only be used for highest level types or when sending packets.
fn to_bytes(&self) -> Result<Vec<u8>> {
let size = self.size();
let mut bytes = Vec::with_capacity(size);
self.write(&mut bytes)?;
debug_assert_eq!(bytes.len(), size, "Io::size() was wrong");
Ok(bytes)
}
}
/// Like [Io] but when a length type is needed.
/// All functions have a type parameter `Len` which should be an integer primitive.
/// For example [String] encodes its content length then its contents.
/// The user can select what type to use for length, which determines max string length.
/// For custom types that implement this the length type should be passed to fields that implement LenIo.
/// If you do not write any length fields that could benefit from this, do not use LenIo and use `Io` instead with the derive macro.
/// The derive macro can be used for example with `#[io(len = u16)]` to set the length type to u16.
pub trait LenIo : Sized {
/// Read data from the reader.
fn read<L: Len>(r: &mut Reader) -> Result<Self>;
/// Write this data to the reader.
fn write<L: Len> (&self, w: &mut Writer) -> Result<()>;
/// Number of bytes this data will take up when written
fn size<L: Len>(&self) -> usize;
/// Create a Vec<u8> and write to it.
/// Should only be used for highest level types or when sending packets.
fn to_bytes<L: Len>(&self) -> Result<Vec<u8>> {
let size = self.size::<L>();
let mut bytes = Vec::with_capacity(size);
self.write::<L>(&mut bytes)?;
debug_assert_eq!(bytes.len(), size, "LenIo::size() was wrong");
Ok(bytes)
}
}
/// Any primitive integer that can be written.
/// Used for `LenIo` functions.
pub trait Len : Io + Into<u64> + TryFrom<u64> {}
impl <T: Io + Into<u64> + TryFrom<u64>> Len for T {}