use std::io;
use std::io::Write;
pub trait ToraWrite {
fn writes<S>(&mut self, s: &S) -> io::Result<()>
where
S: SerializeIo;
fn write_dyn<T, D>(&mut self, d: D) -> io::Result<()>
where
D: AsRef<[T]>,
T: SerializeIo;
}
impl<W> ToraWrite for W
where
W: Write,
{
fn writes<S>(&mut self, s: &S) -> io::Result<()>
where
S: SerializeIo,
{
s.serialize(self)
}
fn write_dyn<T, D>(&mut self, d: D) -> io::Result<()>
where
D: AsRef<[T]>,
T: SerializeIo,
{
let d = d.as_ref();
self.writes(&(d.len() as u32))?;
for obj in d {
self.writes(obj)?;
}
Ok(())
}
}
pub trait SerializeIo {
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: 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())
}
})*
}
}
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 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 &[T]
where
T: SerializeIo,
{
fn serialize<W>(&self, w: &mut W) -> io::Result<()>
where
W: Write,
{
w.write_dyn(self)
}
}