conv_reader_writer

master
Avril 4 years ago
parent 92d7a35dc1
commit 1cb0afbf51
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,22 @@
//! Conversion operations
use super::*;
use std::io::{
self, Write, Read,
};
use error::Error;
/// Convert from a reader to a writer
/// # Returns
/// The number of bytes read from the `input` stream, and the number of bytes written to the `output` stream.
pub fn conv_reader_writer<R: Read, W: Write>(input: R, input_format: FormatKind, output: W, output_format: FormatKind) -> Result<(usize, usize), Error>
{
let cfg = formats::config::Config::default();
let input_format = input_format.directive();
let output_format = output_format.directive();
let (obj, read) = input_format.call_decode(&cfg, input)?;
let write = output_format.call_encode(&cfg, output, &obj)?;
Ok((read, write))
}

@ -0,0 +1,167 @@
//! Formatting error(s).
use super::*;
use std::{
error, fmt,
io,
};
/// A formatting error kind. See `Error`.
#[derive(Debug)]
pub enum ErrorKind
{
IO(io::Error),
Json(serde_json::Error),
Cbor(serde_cbor::Error),
Lexpr(serde_lexpr::Error),
/// Unknown format ID
UnknownFormat(u32),
/// Unknown error
Unknown,
}
impl error::Error for ErrorKind
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match &self {
ErrorKind::IO(i) => i,
ErrorKind::Json(i) => i,
ErrorKind::Cbor(i) => i,
ErrorKind::Lexpr(i) => i,
_ => return None,
})
}
}
impl fmt::Display for ErrorKind
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
Self::IO(_) => write!(f, "io"),
Self::Json(_) => write!(f, "conv json"),
Self::Cbor(_) => write!(f, "conv cbor"),
Self::Lexpr(_) => write!(f, "conv lexpr"),
Self::UnknownFormat(fmt) => write!(f, "unknown format ID: {}", fmt),
_ => write!(f, "unknown error")
}
}
}
impl From<io::Error> for ErrorKind
{
fn from(from: io::Error) -> Self
{
Self::IO(from)
}
}
impl From<serde_json::Error> for ErrorKind
{
fn from(from: serde_json::Error) -> Self
{
Self::Json(from)
}
}
impl From<serde_cbor::Error> for ErrorKind
{
fn from(from: serde_cbor::Error) -> Self
{
Self::Cbor(from)
}
}
impl From<serde_lexpr::Error> for ErrorKind
{
fn from(from: serde_lexpr::Error) -> Self
{
Self::Lexpr(from)
}
}
/// A formatting error.
#[derive(Debug)]
pub struct Error(Box<ErrorKind>, bool);
impl Error
{
/// An encode error
#[inline] pub fn encode(kind: impl Into<ErrorKind>) -> Self
{
Self(Box::new(kind.into()), true)
}
/// A decode error
#[inline] pub fn decode(kind: impl Into<ErrorKind>) -> Self
{
Self(Box::new(kind.into()), false)
}
/// What kind of error was it?
#[inline] pub fn kind(&self) -> &ErrorKind
{
&self.0
}
/// Consume into the kind of error, which contains the original error object from the conversion (if there is one)
#[inline] pub fn into_inner(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
{
#[inline] fn source(&self) -> Option<&(dyn error::Error + 'static)> {
use error::Error;
self.0.source()
}
}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "formatting error in ")?;
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(Box::new(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),
}
}
}

@ -6,13 +6,12 @@ use std::convert::TryFrom;
use object::Object;
/// `Format` impl for JSON.
mod json;
pub mod json;
/// `Format` impl for S expressions.
mod sexpr;
pub mod sexpr;
/// `Format` impl for CBOR.
mod cbor;
pub mod cbor;
pub mod error;
use error::*;
pub mod config;
@ -26,6 +25,22 @@ pub struct FormatDirective
decode: fn (&Config, &mut dyn io::Read) -> Result<(Object, usize), Error>,
}
impl FormatDirective
{
/// Call the decode method of this directive
#[inline(always)] pub fn call_decode(&self, cfg: &Config, mut stream: impl io::Read) -> Result<(Object, usize), Error>
{
let call = self.decode;
call(cfg, &mut stream)
}
/// Call the encode method of this directive
#[inline(always)] pub fn call_encode(&self, cfg: &Config, mut stream: impl io::Write, obj: &Object) -> Result<usize, Error>
{
let call = self.encode;
call(cfg, &mut stream, obj)
}
}
/// Trait for statically implementing formatters to/from `Object`.
pub trait Format
{
@ -58,6 +73,13 @@ pub static FORMATS: &[(&'static [&'static str], FormatDirective)] = &[
directive!(for cbor::CborFormatter => "cbor"),
];
/// Directives in a lookup stream
pub static DIRECTIVES: &[&'static FormatDirective; 3] = &[
&FORMATS[0].1,
&FORMATS[1].1,
&FORMATS[2].1,
];
pub(crate) const FORMAT_KIND_JSON: u32 = FormatKind::Json as u32;
pub(crate) const FORMAT_KIND_SEXPR: u32 = FormatKind::SExpr as u32;
pub(crate) const FORMAT_KIND_CBOR: u32 = FormatKind::CBor as u32;
@ -71,6 +93,15 @@ pub enum FormatKind
CBor = 3,
}
impl FormatKind
{
/// Get the directive for this format kind
#[inline] pub fn directive(&self) -> &FormatDirective
{
DIRECTIVES[u32::from(*self) as usize]
}
}
impl From<FormatKind> for u32
{
fn from(from: FormatKind) -> Self

@ -0,0 +1 @@
avril@eientei.14063:1621696860

@ -7,10 +7,13 @@ mod ext; use ext::*;
// Internal modules
pub mod object;
pub mod formats;
pub mod error;
pub use formats::FormatKind;
// TODO: External modules/functions/types/whatever
mod conv;
pub use conv::*;
// TODO: FFI module, export C interface

Loading…
Cancel
Save