http_types/transfer/
transfer_encoding.rs

1use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, CONTENT_ENCODING};
2use crate::transfer::{Encoding, EncodingProposal};
3
4use std::fmt::{self, Debug};
5use std::ops::{Deref, DerefMut};
6use std::option;
7
8/// The form of encoding used to safely transfer the payload body to the user.
9///
10/// [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding)
11///
12/// # Specifications
13///
14/// - [RFC 7230, section 3.3.1: Transfer-Encoding](https://tools.ietf.org/html/rfc7230#section-3.3.1)
15///
16/// # Examples
17///
18/// ```
19/// # fn main() -> http_types::Result<()> {
20/// #
21/// use http_types::Response;
22/// use http_types::transfer::{TransferEncoding, Encoding};
23/// let mut encoding = TransferEncoding::new(Encoding::Chunked);
24///
25/// let mut res = Response::new(200);
26/// encoding.apply(&mut res);
27///
28/// let encoding = TransferEncoding::from_headers(res)?.unwrap();
29/// assert_eq!(encoding, &Encoding::Chunked);
30/// #
31/// # Ok(()) }
32/// ```
33pub struct TransferEncoding {
34    inner: Encoding,
35}
36
37impl TransferEncoding {
38    /// Create a new instance of `CacheControl`.
39    pub fn new(encoding: Encoding) -> Self {
40        Self { inner: encoding }
41    }
42
43    /// Create a new instance from headers.
44    pub fn from_headers(headers: impl AsRef<Headers>) -> crate::Result<Option<Self>> {
45        let headers = match headers.as_ref().get(CONTENT_ENCODING) {
46            Some(headers) => headers,
47            None => return Ok(None),
48        };
49
50        let mut inner = None;
51
52        for value in headers {
53            if let Some(entry) = Encoding::from_str(value.as_str()) {
54                inner = Some(entry);
55            }
56        }
57
58        let inner = inner.expect("Headers instance with no entries found");
59        Ok(Some(Self { inner }))
60    }
61
62    /// Sets the `Content-Encoding` header.
63    pub fn apply(&self, mut headers: impl AsMut<Headers>) {
64        headers.as_mut().insert(CONTENT_ENCODING, self.value());
65    }
66
67    /// Get the `HeaderName`.
68    pub fn name(&self) -> HeaderName {
69        CONTENT_ENCODING
70    }
71
72    /// Get the `HeaderValue`.
73    pub fn value(&self) -> HeaderValue {
74        self.inner.into()
75    }
76
77    /// Access the encoding kind.
78    pub fn encoding(&self) -> Encoding {
79        self.inner
80    }
81}
82
83impl ToHeaderValues for TransferEncoding {
84    type Iter = option::IntoIter<HeaderValue>;
85    fn to_header_values(&self) -> crate::Result<Self::Iter> {
86        // A HeaderValue will always convert into itself.
87        Ok(self.value().to_header_values().unwrap())
88    }
89}
90
91impl Deref for TransferEncoding {
92    type Target = Encoding;
93    fn deref(&self) -> &Self::Target {
94        &self.inner
95    }
96}
97
98impl DerefMut for TransferEncoding {
99    fn deref_mut(&mut self) -> &mut Self::Target {
100        &mut self.inner
101    }
102}
103
104impl PartialEq<Encoding> for TransferEncoding {
105    fn eq(&self, other: &Encoding) -> bool {
106        &self.inner == other
107    }
108}
109
110impl PartialEq<&Encoding> for TransferEncoding {
111    fn eq(&self, other: &&Encoding) -> bool {
112        &&self.inner == other
113    }
114}
115
116impl From<Encoding> for TransferEncoding {
117    fn from(encoding: Encoding) -> Self {
118        Self { inner: encoding }
119    }
120}
121
122impl From<&Encoding> for TransferEncoding {
123    fn from(encoding: &Encoding) -> Self {
124        Self { inner: *encoding }
125    }
126}
127
128impl From<EncodingProposal> for TransferEncoding {
129    fn from(encoding: EncodingProposal) -> Self {
130        Self {
131            inner: encoding.encoding,
132        }
133    }
134}
135
136impl From<&EncodingProposal> for TransferEncoding {
137    fn from(encoding: &EncodingProposal) -> Self {
138        Self {
139            inner: encoding.encoding,
140        }
141    }
142}
143
144impl Debug for TransferEncoding {
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        self.inner.fmt(f)
147    }
148}