From f8845906411a073d9aa3ed60b9b882f9c6a1b5e3 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 19 May 2021 19:35:24 +0100 Subject: [PATCH] start rework design --- Cargo.toml | 1 + src/ext.rs | 3 ++ src/formats.rs | 55 +++++++++++++----------------- src/lib.rs | 4 ++- src/object.rs | 29 ++++++++++++++++ src/processor.rs | 89 ------------------------------------------------ 6 files changed, 59 insertions(+), 122 deletions(-) create mode 100644 src/ext.rs create mode 100644 src/object.rs delete mode 100644 src/processor.rs diff --git a/Cargo.toml b/Cargo.toml index fb4e97f..c44641c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ serde = {version = "1.0.126", features = ["derive"]} serde-lexpr = "0.1.2" serde_cbor = "0.11.1" serde_json = "1.0.64" +smallbox = "0.8.0" diff --git a/src/ext.rs b/src/ext.rs new file mode 100644 index 0000000..a3c9978 --- /dev/null +++ b/src/ext.rs @@ -0,0 +1,3 @@ +use super::*; + +pub use object::ObjectExt; diff --git a/src/formats.rs b/src/formats.rs index ddf3ab6..3a4e4ac 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -1,41 +1,32 @@ //! The available formats to convert use super::*; -use processor::Processor; +use std::io; +use object::{ + Object, OwnedObject, +}; -/// All formats and their associated processor -pub enum Format +pub struct Config; + +/// A directive for a format on how to encode and decode objects. +#[derive(Clone, Copy)] +pub struct FormatDirective { - Json(processor::Json), - SExpr(processor::Sexpr), - CBor(processor::Cbor), + encode: fn (&Config, &mut dyn io::Write, &dyn Object) -> io::Result, + decode: fn (&Config, &mut dyn io::Read) -> io::Result<(OwnedObject<'static>, usize)>, } -impl Format -{ - /// The processor for this format - pub fn processor(&self) -> &(dyn Processor + 'static) - { - match &self { - Self::Json(a) => a, - Self::SExpr(a) => a, - Self::CBor(a) => a, - } - } - - /// The processor for this format - pub fn processor_mut(&mut self) -> &mut (dyn Processor + 'static) - { - match self { - Self::Json(a) => a, - Self::SExpr(a) => a, - Self::CBor(a) => a, - } - } +macro_rules! directive { + ($($name:literal),+ => $encode:expr, $decode:expr) => { + (&[$($name),+], FormatDirective { + encode: $encode, + decode: $decode, + }) + }; } -/// All format objects and their name(s) -pub static FORMATS: &[(&'static [&'static str], Format)] = &[ - (&["json"], Format::Json(processor::Json)), - (&["s-expression", "sexpr"], Format::SExpr(processor::Sexpr)), - (&["cbor"], Format::CBor(processor::Cbor)), +/// All format directives and their name(s) +pub static FORMATS: &[(&'static [&'static str], FormatDirective)] = &[ + directive!("json" => |_, _, _| todo!(), |_, _| todo!()), + directive!("s-expression", "sexpr" => |_, _, _| todo!(), |_, _| todo!()), + directive!("cbor" => |_, _, _| todo!(), |_, _| todo!()), ]; diff --git a/src/lib.rs b/src/lib.rs index f0581d9..5e0ae84 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ #![allow(dead_code)] -mod processor; +mod ext; use ext::*; + +mod object; mod formats; #[cfg(test)] diff --git a/src/object.rs b/src/object.rs new file mode 100644 index 0000000..bfe96e1 --- /dev/null +++ b/src/object.rs @@ -0,0 +1,29 @@ +use super::*; +use smallbox::{ + SmallBox, + space, + smallbox, +}; + +type OwnedObjectStackSize = space::S4; + +/// An object that can be expose serialise+deserialise methods +pub trait Object{ + // TODO +} + +/// A polymorphic `Object` that is owned. +pub type OwnedObject<'a> = SmallBox; + +pub trait ObjectExt<'a>: Sized +{ + fn into_owned(self) -> OwnedObject<'a>; +} + +impl<'a, T: 'a> ObjectExt<'a> for T +where T: Object +{ + #[inline] fn into_owned(self) -> OwnedObject<'a> { + smallbox!(self) + } +} diff --git a/src/processor.rs b/src/processor.rs deleted file mode 100644 index 4c3e2ed..0000000 --- a/src/processor.rs +++ /dev/null @@ -1,89 +0,0 @@ -//! Processing -use super::*; -use std::io; -use std::{ - fmt, error -}; - -macro_rules! processor { - ($name:ident: {$($body:tt)*}) => { - #[derive(Debug)] - pub struct $name; - - impl Processor for $name{$($body)*} - }; -} - -//TODO: Move this to `object.rs`. Have a type that polymorphises any `Serialize` object, somehow... -//This may be impossible. If it is. Nuke this file, and re-do the `FORMATS` table's value type to `fn(...SOMETHING...) -> io::Result<...SOMETHING...>` -pub type Object = (); - -pub trait Processor -{ - //TODO: How to design this trait??? eh... - fn read_object(&self, input: &mut dyn io::Read) -> Result; - fn write_object(&self, obj: &Object, output: &mut dyn io::Write) -> Result; -} - -processor!(Json: { - -}); -processor!(Sexpr: { - -}); -processor!(Cbor: { - -}); - -#[derive(Debug)] -enum ErrorKind -{ - IO(io::Error), - Unknown, -} - -/// Processing error -pub struct Error(ErrorKind, Option>); - -impl fmt::Debug for Error -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result - { - f.debug_struct("Error") - .field("kind", &self.0) - .field("message_obj", &format_args!("{:?}", self.1.as_ref().map(|x| x.as_ref() as *const _))) - .finish() - } -} - - -impl From for Error -{ - #[inline] fn from(from: io::Error) -> Self - { - Self(ErrorKind::IO(from), None) - } -} - -impl error::Error for Error -{ - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - Some(match &self.0 { - ErrorKind::IO(io) => io, - _ => return None, - }) - } -} - -impl fmt::Display for Error -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result - { - write!(f, "format processing error")?; - if let Some(msg) = self.1.as_ref() { - write!(f, ": {}", msg) - } else { - Ok(()) - } - } -}