feim 0.25.1

Modular crate for working with images in Rust
Documentation
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)
}