parent
070f9bbb7e
commit
f884590641
@ -0,0 +1,3 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub use object::ObjectExt;
|
@ -1,41 +1,32 @@
|
|||||||
//! The available formats to convert
|
//! The available formats to convert
|
||||||
use super::*;
|
use super::*;
|
||||||
use processor::Processor;
|
use std::io;
|
||||||
|
use object::{
|
||||||
|
Object, OwnedObject,
|
||||||
|
};
|
||||||
|
|
||||||
/// All formats and their associated processor
|
pub struct Config;
|
||||||
pub enum Format
|
|
||||||
{
|
|
||||||
Json(processor::Json),
|
|
||||||
SExpr(processor::Sexpr),
|
|
||||||
CBor(processor::Cbor),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Format
|
/// A directive for a format on how to encode and decode objects.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct FormatDirective
|
||||||
{
|
{
|
||||||
/// The processor for this format
|
encode: fn (&Config, &mut dyn io::Write, &dyn Object) -> io::Result<usize>,
|
||||||
pub fn processor(&self) -> &(dyn Processor + 'static)
|
decode: fn (&Config, &mut dyn io::Read) -> io::Result<(OwnedObject<'static>, usize)>,
|
||||||
{
|
}
|
||||||
match &self {
|
|
||||||
Self::Json(a) => a,
|
|
||||||
Self::SExpr(a) => a,
|
|
||||||
Self::CBor(a) => a,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The processor for this format
|
macro_rules! directive {
|
||||||
pub fn processor_mut(&mut self) -> &mut (dyn Processor + 'static)
|
($($name:literal),+ => $encode:expr, $decode:expr) => {
|
||||||
{
|
(&[$($name),+], FormatDirective {
|
||||||
match self {
|
encode: $encode,
|
||||||
Self::Json(a) => a,
|
decode: $decode,
|
||||||
Self::SExpr(a) => a,
|
})
|
||||||
Self::CBor(a) => a,
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All format objects and their name(s)
|
/// All format directives and their name(s)
|
||||||
pub static FORMATS: &[(&'static [&'static str], Format)] = &[
|
pub static FORMATS: &[(&'static [&'static str], FormatDirective)] = &[
|
||||||
(&["json"], Format::Json(processor::Json)),
|
directive!("json" => |_, _, _| todo!(), |_, _| todo!()),
|
||||||
(&["s-expression", "sexpr"], Format::SExpr(processor::Sexpr)),
|
directive!("s-expression", "sexpr" => |_, _, _| todo!(), |_, _| todo!()),
|
||||||
(&["cbor"], Format::CBor(processor::Cbor)),
|
directive!("cbor" => |_, _, _| todo!(), |_, _| todo!()),
|
||||||
];
|
];
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
use super::*;
|
||||||
|
use smallbox::{
|
||||||
|
SmallBox,
|
||||||
|
space,
|
||||||
|
smallbox,
|
||||||
|
};
|
||||||
|
|
||||||
|
type OwnedObjectStackSize = space::S4;
|
||||||
|
|
||||||
|
/// An object that can be expose serialise+deserialise methods
|
||||||
|
pub trait Object{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A polymorphic `Object` that is owned.
|
||||||
|
pub type OwnedObject<'a> = SmallBox<dyn Object + 'a, OwnedObjectStackSize>;
|
||||||
|
|
||||||
|
pub trait ObjectExt<'a>: Sized
|
||||||
|
{
|
||||||
|
fn into_owned(self) -> OwnedObject<'a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a> ObjectExt<'a> for T
|
||||||
|
where T: Object
|
||||||
|
{
|
||||||
|
#[inline] fn into_owned(self) -> OwnedObject<'a> {
|
||||||
|
smallbox!(self)
|
||||||
|
}
|
||||||
|
}
|
@ -1,89 +0,0 @@
|
|||||||
//! 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<Object, Error>;
|
|
||||||
fn write_object(&self, obj: &Object, output: &mut dyn io::Write) -> Result<usize, Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
processor!(Json: {
|
|
||||||
|
|
||||||
});
|
|
||||||
processor!(Sexpr: {
|
|
||||||
|
|
||||||
});
|
|
||||||
processor!(Cbor: {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ErrorKind
|
|
||||||
{
|
|
||||||
IO(io::Error),
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Processing error
|
|
||||||
pub struct Error(ErrorKind, Option<Box<dyn fmt::Display + 'static>>);
|
|
||||||
|
|
||||||
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<io::Error> 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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue