Refactor gzip and brotli bools into an Accepts struct

This commit is contained in:
Sean McArthur
2020-03-03 16:10:06 -08:00
parent 2f875255e1
commit a06e03edf4
4 changed files with 94 additions and 44 deletions

View File

@@ -18,6 +18,14 @@ use hyper::body::HttpBody;
use super::super::Body;
use crate::error;
#[derive(Clone, Copy, Debug)]
pub(super) struct Accepts {
#[cfg(feature = "gzip")]
pub(super) gzip: bool,
#[cfg(feature = "brotli")]
pub(super) brotli: bool,
}
/// A response decompressor over a non-blocking stream of chunks.
///
/// The inner decoder may be constructed asynchronously.
@@ -25,13 +33,6 @@ pub(crate) struct Decoder {
inner: Inner,
}
enum DecoderType {
#[cfg(feature = "gzip")]
Gzip,
#[cfg(feature = "brotli")]
Brotli,
}
enum Inner {
/// A `PlainText` decoder just returns the response content as is.
PlainText(super::body::ImplStream),
@@ -54,6 +55,13 @@ struct Pending(Peekable<IoStream>, DecoderType);
struct IoStream(super::body::ImplStream);
enum DecoderType {
#[cfg(feature = "gzip")]
Gzip,
#[cfg(feature = "brotli")]
Brotli,
}
impl fmt::Debug for Decoder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Decoder").finish()
@@ -177,26 +185,21 @@ impl Decoder {
/// how to decode the content body of the request.
///
/// Uses the correct variant by inspecting the Content-Encoding header.
pub(crate) fn detect(
pub(super) fn detect(
_headers: &mut HeaderMap,
body: Body,
check_gzip: bool,
check_brotli: bool,
_accepts: Accepts,
) -> Decoder {
if !check_gzip && !check_brotli {
return Decoder::plain_text(body);
}
#[cfg(feature = "gzip")]
{
if Decoder::detect_gzip(_headers) {
if _accepts.gzip && Decoder::detect_gzip(_headers) {
return Decoder::gzip(body);
}
}
#[cfg(feature = "brotli")]
{
if Decoder::detect_brotli(_headers) {
if _accepts.brotli && Decoder::detect_brotli(_headers) {
return Decoder::brotli(body);
}
}
@@ -317,3 +320,60 @@ impl Stream for IoStream {
}
}
}
// ===== impl Accepts =====
impl Accepts {
pub(super) fn none() -> Self {
Accepts {
#[cfg(feature = "gzip")]
gzip: false,
#[cfg(feature = "brotli")]
brotli: false,
}
}
pub(super) fn as_str(&self) -> Option<&'static str> {
match (self.is_gzip(), self.is_brotli()) {
(true, true) => Some("gzip, br"),
(true, false) => Some("gzip"),
(false, true) => Some("br"),
_ => None,
}
}
fn is_gzip(&self) -> bool {
#[cfg(feature = "gzip")]
{
self.gzip
}
#[cfg(not(feature = "gzip"))]
{
false
}
}
fn is_brotli(&self) -> bool {
#[cfg(feature = "brotli")]
{
self.brotli
}
#[cfg(not(feature = "brotli"))]
{
false
}
}
}
impl Default for Accepts {
fn default() -> Accepts {
Accepts {
#[cfg(feature = "gzip")]
gzip: true,
#[cfg(feature = "brotli")]
brotli: true,
}
}
}