use std::io::{self, BufRead, Read, Write};
use crate::image::Format;
use crate::specialized::{Aye, No};
pub trait EncodeOptions {
type Options;
}
pub trait DecodeOptions {
type Options;
}
pub trait Encode<B, Specialized = Aye>: EncodeOptions {
type Error;
fn encode<W: Write>(w: W, opts: Self::Options, buf: &B) -> Result<(), Self::Error>;
}
pub trait EncodeSpecialized<B>: EncodeOptions {
type Error;
fn encode_specialized<W: Write>(w: W, opts: Self::Options, buf: &B) -> Result<(), Self::Error>;
}
impl<B, F: Encode<B, Aye>> EncodeSpecialized<B> for F {
type Error = <F as Encode<B, Aye>>::Error;
#[inline]
fn encode_specialized<W: Write>(w: W, opts: Self::Options, buf: &B) -> Result<(), Self::Error> {
Self::encode(w, opts, buf)
}
}
pub trait EncodeGeneric<B>: EncodeOptions {
type Error;
fn encode_generic<W: Write>(w: W, opts: Self::Options, buf: &B) -> Result<(), Self::Error>;
}
impl<B, F: Encode<B, No>> EncodeGeneric<B> for F {
type Error = <F as Encode<B, No>>::Error;
#[inline]
fn encode_generic<W: Write>(w: W, opts: Self::Options, buf: &B) -> Result<(), Self::Error> {
Self::encode(w, opts, buf)
}
}
pub trait Decode<B, Specialized = Aye>: DecodeOptions {
type Error;
fn decode<R: Read>(r: R, opt: Self::Options) -> Result<B, Self::Error>;
}
pub trait DecodeSpecialized<B>: DecodeOptions {
type Error;
fn decode_specialized<R: Read>(r: R, opt: Self::Options) -> Result<B, Self::Error>;
}
impl<B, F: Decode<B, Aye>> DecodeSpecialized<B> for F {
type Error = <F as Decode<B, Aye>>::Error;
#[inline]
fn decode_specialized<R: Read>(r: R, opt: Self::Options) -> Result<B, Self::Error> {
Self::decode(r, opt)
}
}
pub trait DecodeGeneric<B>: DecodeOptions {
type Error;
fn decode_generic<R: Read>(r: R, opt: Self::Options) -> Result<B, Self::Error>;
}
impl<B, F: Decode<B, No>> DecodeGeneric<B> for F {
type Error = <F as Decode<B, No>>::Error;
#[inline]
fn decode_generic<R: Read>(r: R, opt: Self::Options) -> Result<B, Self::Error> {
Self::decode(r, opt)
}
}
pub fn try_format<'f, I, F, R>(mut r: R, formats: F) -> io::Result<Option<I>>
where
F: IntoIterator<Item = (I, &'f dyn Format)>,
R: BufRead,
{
let buf = r.fill_buf()?;
for (i, fmt) in formats {
if fmt.is_valid_magic(buf) {
return Ok(Some(i));
}
}
Ok(None)
}