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}