//! The available formats to convert use super::*; use std::io; use object::Object; /// `Format` impl for JSON. mod json; /// `Format` impl for S expressions. mod sexpr; /// `Format` impl for CBOR. mod cbor; pub mod error; use error::*; pub mod config; use config::*; /// 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).map_err(Error::encode) }, |c, r| { let mut r = r.with_counter(); let obj = <$fmt as Format>::decode(c, &mut r).map_err(Error::decode)?; 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!(for sexpr::SExpressionFormatter => "s-expression", "sexpr", "lisp", "lexpr"), directive!(for cbor::CborFormatter => "cbor"), ]; //const _: &[u8; 0] = &[0u8; std::mem::size_of::()]; // Size of error type check (unboxed 56 -> boxed 16)