use super::*; use std::io; use smallbox::{ SmallBox, space, smallbox, }; type OwnedObjectStackSize = space::S4; /// An object that can be expose serialise+deserialise methods polymorphically. pub trait Object { fn to_writer(&self, to: &mut dyn io::Write) -> io::Result; fn from_reader(&mut self, from: &mut dyn io::Read) -> io::Result; //ugh, this SUUUCKS... #[inline] fn to_vec_with_cap(&self, cap: usize) -> io::Result> { let mut string = Vec::with_capacity(cap); self.to_writer(&mut string)?; Ok(string) } #[inline] fn to_vec(&self) -> io::Result> { let mut string = Vec::new(); self.to_writer(&mut string)?; Ok(string) } #[inline] fn from_bytes(&mut self, mut bytes: &[u8]) -> io::Result { self.from_reader(&mut bytes) } } /// A polymorphic `Object` that is owned. pub type OwnedObject<'a> = SmallBox; pub trait ObjectExt<'a>: Sized { /// Consume this object into a dynamic (boxed) one. fn into_owned(self) -> OwnedObject<'a>; } pub trait ObjectNewExt<'a> { /// Create a new object from this reader fn new_obj_from_reader(from: R) -> io::Result<(OwnedObject<'a>, usize)>; } impl<'a, T: 'a> ObjectExt<'a> for T where T: Object { #[inline] fn into_owned(self) -> OwnedObject<'a> { smallbox!(self) } } impl<'a, T: 'a> ObjectNewExt<'a> for T where T: Object + Default { fn new_obj_from_reader(mut from: R) -> io::Result<(OwnedObject<'a>, usize)> { let mut this = T::default(); Ok((this.from_reader(&mut from)?, this.into_owned()).swap()) } }