begin Format impl wrapper for FORMATS array

master
Avril 4 years ago
parent 191a466809
commit 5ac12414eb
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,17 +1,31 @@
//! 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
pub struct Config;
pub struct Config; //TODO: What goes here?
/// 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) -> io::Result<usize>,
decode: fn (&Config, &mut dyn io::Read) -> io::Result<(Object, usize)>,
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, Error>;
fn decode<R: io::Read>(cfg: &Config, from: R) -> Result<Object, Error>; //TODO: An `io::Read` wrapper that counter num of bytes read internally. That way we can extract `(Object, usize)` from just `Object` here.
}
macro_rules! directive {
@ -21,11 +35,117 @@ macro_rules! directive {
decode: $decode,
})
};
(for $fmt:path => $($name:literal),+) => {
//TODO: $fmt will be a struct implementing `Format`.
// Will perform input conversions to trait methods.
// Will perform input/output conversions for `Format::decode` to extract `(Object, usize)` from `Object` function output and a `io::Read` input wrapper that counts bytes read from the stream.
directive!($($name),+ => |c, w, o| {
<$fmt as Format>::encode(c, w, o)
}, |c, r| {
todo!("We need a io::Read stream wrapper that counts the bytes read `r` to satisfy the return value requirements of this function pointer")
})
}
}
/// All format directives and their name(s)
pub static FORMATS: &[(&'static [&'static str], FormatDirective)] = &[
directive!("json", "js", "javascript" => |_, _, _| todo!(), |_, _| todo!()),
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<io::Error> 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<ErrorKind>) -> Self
{
Self(kind.into(), true)
}
/// A decode error
#[inline] pub fn decode(kind: impl Into<ErrorKind>) -> 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<Error> for io::Error
{
fn from(from: Error) -> Self
{
match from.0
{
ErrorKind::IO(io) => io,
_ => io::Error::new(io::ErrorKind::Other, from),
}
}
}

@ -0,0 +1,14 @@
use super::*;
#[derive(Debug)]
pub struct JsonFormatter;
impl Format for JsonFormatter
{
fn encode<W: io::Write>(cfg: &Config, to: W, obj: &Object) -> Result<usize, Error> {
todo!()
}
fn decode<R: io::Read>(cfg: &Config, from: R) -> Result<Object, Error> {
todo!()
}
}
Loading…
Cancel
Save