//! 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(()) } } }