use futures_core::Stream;
use http::header::{HeaderMap, CONTENT_ENCODING};
use super::{
coder::{Coder, FeaturedCode},
coding::ContentEncoding,
error::EncodingError,
};
#[inline]
pub fn try_decoder<S, T, E>(headers: &HeaderMap, body: S) -> Result<Coder<S, FeaturedCode>, EncodingError>
where
S: Stream<Item = Result<T, E>>,
T: AsRef<[u8]> + 'static,
{
from_headers(headers).map(|decoder| Coder::new(body, decoder))
}
fn from_headers(headers: &HeaderMap) -> Result<FeaturedCode, EncodingError> {
let Some(val) = headers.get(&CONTENT_ENCODING) else {
return Ok(FeaturedCode::default());
};
let enc = val.to_str().map_err(|_| EncodingError::ParseAcceptEncoding)?;
match ContentEncoding::try_parse(enc)? {
ContentEncoding::Br => {
#[cfg(feature = "br")]
{
Ok(FeaturedCode::DecodeBr(super::brotli::Decoder::new(
super::writer::BytesMutWriter::new(),
)))
}
#[cfg(not(feature = "br"))]
{
Err(super::error::FeatureError::Br.into())
}
}
ContentEncoding::Gzip => {
#[cfg(feature = "gz")]
{
Ok(FeaturedCode::DecodeGz(super::gzip::Decoder::new(
super::writer::BytesMutWriter::new(),
)))
}
#[cfg(not(feature = "gz"))]
{
Err(super::error::FeatureError::Gzip.into())
}
}
ContentEncoding::Deflate => {
#[cfg(feature = "de")]
{
Ok(FeaturedCode::DecodeDe(super::deflate::Decoder::new(
super::writer::BytesMutWriter::new(),
)))
}
#[cfg(not(feature = "de"))]
{
Err(super::error::FeatureError::Deflate.into())
}
}
ContentEncoding::NoOp => Ok(FeaturedCode::default()),
}
}