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 {}