You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.6 KiB

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<usize>;
fn from_reader(&mut self, from: &mut dyn io::Read) -> io::Result<usize>; //ugh, this SUUUCKS...
#[inline] fn to_vec_with_cap(&self, cap: usize) -> io::Result<Vec<u8>>
{
let mut string = Vec::with_capacity(cap);
self.to_writer(&mut string)?;
Ok(string)
}
#[inline] fn to_vec(&self) -> io::Result<Vec<u8>>
{
let mut string = Vec::new();
self.to_writer(&mut string)?;
Ok(string)
}
#[inline] fn from_bytes(&mut self, mut bytes: &[u8]) -> io::Result<usize>
{
self.from_reader(&mut bytes)
}
}
/// A polymorphic `Object` that is owned.
pub type OwnedObject<'a> = SmallBox<dyn Object + 'a, OwnedObjectStackSize>;
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<R: io::Read>(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<R: io::Read>(mut from: R) -> io::Result<(OwnedObject<'a>, usize)> {
let mut this = T::default();
Ok((this.from_reader(&mut from)?, this.into_owned()).swap())
}
}