use std::io;
use std::io::Write;
macro_rules! serialize_io_num {
($($t:ty),*) => {
$(
impl SerializeIo for $t {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where W: Write
{
w.write_all(&self.to_le_bytes())
}
})*
}
}
pub trait ToraWrite {
fn writes<S>(&mut self, s: &S) -> io::Result<()>
where
S: SerializeIo;
}
impl<W> ToraWrite for W
where
W: Write,
{
fn writes<S>(&mut self, s: &S) -> io::Result<()>
where
S: SerializeIo,
{
s.serialize(self)
}
}
pub trait SerializeIo {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write;
}
serialize_io_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, usize);
impl SerializeIo for char {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
(*self as u32).serialize(w)
}
}
impl SerializeIo for bool {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
(*self as u8).serialize(w)
}
}
impl SerializeIo for () {
fn serialize<W>(&self, _w: &mut W) -> io::Result<()>
where
W: Write,
{
Ok(())
}
}
impl<T, Z> SerializeIo for (T, Z)
where
T: SerializeIo,
Z: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&self.0)?;
w.writes(&self.1)
}
}
impl<T, Z, H> SerializeIo for (T, Z, H)
where
T: SerializeIo,
Z: SerializeIo,
H: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&self.0)?;
w.writes(&self.1)?;
w.writes(&self.2)
}
}
impl SerializeIo for String {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
self.as_str().serialize(w)
}
}
impl<'a> SerializeIo for &'a str {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.write_all(self.as_bytes())?;
if !self.ends_with(0u8 as char) {
w.write_all(&[0])?;
}
Ok(())
}
}
impl<T> SerializeIo for Option<T>
where
T: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&self.is_some())?;
if let Some(ref v) = self {
w.writes(v)?;
}
Ok(())
}
}
impl<T, E> SerializeIo for Result<T, E>
where
T: SerializeIo,
E: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&self.is_err())?;
match self {
Ok(v) => w.writes(v),
Err(v) => w.writes(v),
}
}
}
impl<T, const N: usize> SerializeIo for [T; N]
where
T: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
for t in self {
w.writes(t)?;
}
Ok(())
}
}
impl<T> SerializeIo for Box<T>
where T: SerializeIo
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&**self)
}
}
macro_rules! dyn_impl {
($t: ty) => {
#[cfg(feature = "dyn_impl")]
impl<T> SerializeIo for $t
where
T: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.writes(&(self.len() as u32))?;
for obj in self.iter() {
w.writes(obj)?;
}
Ok(())
}
}
};
}
dyn_impl!(&[T]);
dyn_impl!(Vec<T>);