headers/common/
content_encoding.rs

1use http::HeaderValue;
2
3use self::sealed::AsCoding;
4use crate::util::FlatCsv;
5
6/// `Content-Encoding` header, defined in
7/// [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.2.2)
8///
9/// The `Content-Encoding` header field indicates what content codings
10/// have been applied to the representation, beyond those inherent in the
11/// media type, and thus what decoding mechanisms have to be applied in
12/// order to obtain data in the media type referenced by the Content-Type
13/// header field.  Content-Encoding is primarily used to allow a
14/// representation's data to be compressed without losing the identity of
15/// its underlying media type.
16///
17/// # ABNF
18///
19/// ```text
20/// Content-Encoding = 1#content-coding
21/// ```
22///
23/// # Example values
24///
25/// * `gzip`
26/// * `br`
27/// * `zstd`
28///
29/// # Examples
30///
31/// ```
32/// use headers::ContentEncoding;
33///
34/// let content_enc = ContentEncoding::gzip();
35/// ```
36#[derive(Clone, Debug)]
37pub struct ContentEncoding(FlatCsv);
38
39derive_header! {
40    ContentEncoding(_),
41    name: CONTENT_ENCODING
42}
43
44impl ContentEncoding {
45    /// A constructor to easily create a `Content-Encoding: gzip` header.
46    #[inline]
47    pub fn gzip() -> ContentEncoding {
48        ContentEncoding(HeaderValue::from_static("gzip").into())
49    }
50
51    /// A constructor to easily create a `Content-Encoding: br` header.
52    #[inline]
53    pub fn brotli() -> ContentEncoding {
54        ContentEncoding(HeaderValue::from_static("br").into())
55    }
56
57    /// A constructor to easily create a `Content-Encoding: zstd` header.
58    #[inline]
59    pub fn zstd() -> ContentEncoding {
60        ContentEncoding(HeaderValue::from_static("zstd").into())
61    }
62
63    /// Check if this header contains a given "coding".
64    ///
65    /// This can be used with these argument types:
66    ///
67    /// - `&str`
68    ///
69    /// # Example
70    ///
71    /// ```
72    /// use headers::ContentEncoding;
73    ///
74    /// let content_enc = ContentEncoding::gzip();
75    ///
76    /// assert!(content_enc.contains("gzip"));
77    /// assert!(!content_enc.contains("br"));
78    /// ```
79    pub fn contains(&self, coding: impl AsCoding) -> bool {
80        let s = coding.as_coding();
81        self.0.iter().any(|opt| opt == s)
82    }
83}
84
85mod sealed {
86    pub trait AsCoding: Sealed {}
87
88    pub trait Sealed {
89        fn as_coding(&self) -> &str;
90    }
91
92    impl AsCoding for &str {}
93
94    impl Sealed for &str {
95        fn as_coding(&self) -> &str {
96            self
97        }
98    }
99}