diff --git a/Cargo.toml b/Cargo.toml index eaf1629..fb4e97f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,7 @@ codegen-units = 1 panic = "unwind" [dependencies] +serde = {version = "1.0.126", features = ["derive"]} +serde-lexpr = "0.1.2" +serde_cbor = "0.11.1" +serde_json = "1.0.64" diff --git a/src/formats.rs b/src/formats.rs new file mode 100644 index 0000000..ddf3ab6 --- /dev/null +++ b/src/formats.rs @@ -0,0 +1,41 @@ +//! The available formats to convert +use super::*; +use processor::Processor; + +/// All formats and their associated processor +pub enum Format +{ + Json(processor::Json), + SExpr(processor::Sexpr), + CBor(processor::Cbor), +} + +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, + } + } +} + +/// 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)), +]; diff --git a/src/lib.rs b/src/lib.rs index d3126d3..f0581d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,9 @@ +#![allow(dead_code)] + +mod processor; +mod formats; + #[cfg(test)] mod tests { #[test] diff --git a/src/processor.rs b/src/processor.rs new file mode 100644 index 0000000..63bf31d --- /dev/null +++ b/src/processor.rs @@ -0,0 +1,84 @@ +//! 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)*} + }; +} + +pub trait Processor +{ + //TODO: How to design this trait??? eh... + fn process_stream(&self, input: &mut dyn serde::Serialize, 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(()) + } + } +}