//! The available formats to convert use super::*; use std::io; use std::{ error, fmt, }; use object::Object; /// `Format` impl for JSON. mod json; /// Config for the encode/decode #[derive(Debug)] pub struct Config{ //TODO: What goes here? /// Any arbitrary data. pub user: Option, } /// A directive for a format on how to encode and decode objects. #[derive(Clone, Copy)] pub struct FormatDirective { encode: fn (&Config, &mut dyn io::Write, &Object) -> Result, decode: fn (&Config, &mut dyn io::Read) -> Result<(Object, usize), Error>, } /// Trait for statically implementing formatters to/from `Object`. pub trait Format { fn encode(cfg: &Config, to: W, obj: &Object) -> Result; fn decode(cfg: &Config, from: R) -> Result; } macro_rules! directive { ($($name:literal),+ => $encode:expr, $decode:expr) => { (&[$($name),+], FormatDirective { encode: $encode, decode: $decode, }) }; (for $fmt:path => $($name:literal),+) => { directive!($($name),+ => |c, w, o| { <$fmt as Format>::encode(c, w, o) }, |c, r| { let mut r = r.with_counter(); let obj = <$fmt as Format>::decode(c, &mut r)?; Ok((obj, r.count())) }) } } /// All format directives and their name(s) pub static FORMATS: &[(&'static [&'static str], FormatDirective)] = &[ directive!(for json::JsonFormatter => "json", "js", "javascript"), directive!("s-expression", "sexpr", "lisp", "lexpr" => |_, _, _| todo!(), |_, _| todo!()), directive!("cbor" => |_, _, _| todo!(), |_, _| todo!()), ]; /// A formatting error kind. See `Error`. #[derive(Debug)] pub enum ErrorKind { IO(io::Error), Unknown, } impl From for ErrorKind { fn from(from: io::Error) -> Self { Self::IO(from) } } /// A formatting error. #[derive(Debug)] pub struct Error(ErrorKind, bool); impl Error { /// An encode error #[inline] pub fn encode(kind: impl Into) -> Self { Self(kind.into(), true) } /// A decode error #[inline] pub fn decode(kind: impl Into) -> Self { Self(kind.into(), false) } /// What kind of error was it? #[inline] pub fn kind(&self) -> &ErrorKind { &self.0 } /// Is an encode error? #[inline] pub fn is_encode(&self) -> bool { self.1 } /// Is a decode error? #[inline] pub fn is_decode(&self) -> bool { !self.1 } } impl error::Error for Error { fn source(&self) -> Option<&(dyn error::Error + 'static)> { Some(match &self.0 { ErrorKind::IO(i) => i, _ => return None, }) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "formatting error: ")?; if self.1 { write!(f, "encode") } else { write!(f, "decode") } } } impl From<(io::Error, bool)> for Error { #[inline] fn from(from: (io::Error, bool)) -> Self { Self(ErrorKind::IO(from.0), from.1) } } impl From for io::Error { fn from(from: Error) -> Self { match from.0 { ErrorKind::IO(io) => io, _ => io::Error::new(io::ErrorKind::Other, from), } } }