You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.7 KiB

//! 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<usize, Error>,
decode: fn (&Config, &mut dyn io::Read) -> Result<(Object, usize), Error>,
}
/// Trait for statically implementing formatters to/from `Object`.
pub trait Format
{
fn encode<W: io::Write>(cfg: &Config, to: W, obj: &Object) -> Result<usize, ErrorKind>;
fn decode<R: io::Read>(cfg: &Config, from: R) -> Result<Object, ErrorKind>;
}
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::<Error>()]; // Size of error type check (unboxed 56 -> boxed 16)