use std::error::Error;
use std::io;
pub trait FormatInfo {
fn file_extension(&self) -> &str;
fn is_utf8(&self) -> bool {
false
}
}
pub trait FormatEncoder<V: ?Sized> {
type EncodeError;
fn encode(&mut self, writer: impl io::Write, value: &V) -> Result<(), Self::EncodeError>;
}
pub trait FormatDecoder<V> {
type DecodeError;
fn decode(&mut self, reader: impl io::Read) -> Result<V, Self::DecodeError>;
}
pub trait FormatEncoderDyn<V: ?Sized, E = Box<dyn Error>> {
fn encode_dyn(&mut self, writer: &mut dyn io::Write, value: &V) -> Result<(), E>;
}
pub trait FormatDecoderDyn<V, E = Box<dyn Error>> {
fn decode_dyn(&mut self, reader: &mut dyn io::Read) -> Result<V, E>;
}
impl<T, V> FormatEncoder<V> for &mut T
where
T: ?Sized,
V: ?Sized,
T: FormatEncoder<V>,
{
type EncodeError = T::EncodeError;
fn encode(&mut self, writer: impl io::Write, value: &V) -> Result<(), Self::EncodeError> {
T::encode(self, writer, value)
}
}
impl<T, V> FormatEncoder<V> for Box<T>
where
T: ?Sized,
V: ?Sized,
T: FormatEncoder<V>,
{
type EncodeError = T::EncodeError;
fn encode(&mut self, writer: impl io::Write, value: &V) -> Result<(), Self::EncodeError> {
T::encode(self, writer, value)
}
}
impl<T, V> FormatDecoder<V> for &mut T
where
T: ?Sized,
T: FormatDecoder<V>,
{
type DecodeError = T::DecodeError;
fn decode(&mut self, reader: impl io::Read) -> Result<V, Self::DecodeError> {
T::decode(self, reader)
}
}
impl<T, V> FormatDecoder<V> for Box<T>
where
T: ?Sized,
T: FormatDecoder<V>,
{
type DecodeError = T::DecodeError;
fn decode(&mut self, reader: impl io::Read) -> Result<V, Self::DecodeError> {
T::decode(self, reader)
}
}
impl<T, V, E> FormatEncoderDyn<V, E> for T
where
T: FormatEncoder<V> + ?Sized,
V: ?Sized,
T::EncodeError: Into<E>,
{
fn encode_dyn(&mut self, writer: &mut dyn io::Write, value: &V) -> Result<(), E> {
self.encode(writer, value).map_err(Into::into)
}
}
impl<T, V, E> FormatDecoderDyn<V, E> for T
where
T: FormatDecoder<V> + ?Sized,
T::DecodeError: Into<E>,
{
fn decode_dyn(&mut self, reader: &mut dyn io::Read) -> Result<V, E> {
self.decode(reader).map_err(Into::into)
}
}