http_types_2/headers/
headers.rs1use std::collections::HashMap;
4use std::convert::Into;
5use std::fmt::{self, Debug};
6use std::iter::IntoIterator;
7use std::ops::Index;
8use std::str::FromStr;
9
10use crate::headers::{
11 HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values,
12};
13
14#[derive(Clone)]
31pub struct Headers {
32 pub(crate) headers: HashMap<HeaderName, HeaderValues>,
33}
34
35impl Headers {
36 pub(crate) fn new() -> Self {
38 Self {
39 headers: HashMap::new(),
40 }
41 }
42
43 pub fn insert(
49 &mut self,
50 name: impl Into<HeaderName>,
51 values: impl ToHeaderValues,
52 ) -> crate::Result<Option<HeaderValues>> {
53 let name = name.into();
54 let values: HeaderValues = values.to_header_values()?.collect();
55 Ok(self.headers.insert(name, values))
56 }
57
58 pub fn append(
63 &mut self,
64 name: impl Into<HeaderName>,
65 values: impl ToHeaderValues,
66 ) -> crate::Result<()> {
67 let name = name.into();
68 match self.get_mut(&name) {
69 Some(headers) => {
70 let mut values: HeaderValues = values.to_header_values()?.collect();
71 headers.append(&mut values);
72 }
73 None => {
74 self.insert(name, values)?;
75 }
76 }
77 Ok(())
78 }
79
80 pub fn get(&self, name: impl Into<HeaderName>) -> Option<&HeaderValues> {
82 self.headers.get(&name.into())
83 }
84
85 pub fn get_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValues> {
87 self.headers.get_mut(&name.into())
88 }
89
90 pub fn remove(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValues> {
92 self.headers.remove(&name.into())
93 }
94
95 pub fn iter(&self) -> Iter<'_> {
97 Iter {
98 inner: self.headers.iter(),
99 }
100 }
101
102 pub fn iter_mut(&mut self) -> IterMut<'_> {
105 IterMut {
106 inner: self.headers.iter_mut(),
107 }
108 }
109
110 pub fn names(&self) -> Names<'_> {
112 Names {
113 inner: self.headers.keys(),
114 }
115 }
116
117 pub fn values(&self) -> Values<'_> {
119 Values::new(self.headers.values())
120 }
121}
122
123impl Index<HeaderName> for Headers {
124 type Output = HeaderValues;
125
126 #[inline]
132 fn index(&self, name: HeaderName) -> &HeaderValues {
133 self.get(name).expect("no entry found for name")
134 }
135}
136
137impl Index<&str> for Headers {
138 type Output = HeaderValues;
139
140 #[inline]
146 fn index(&self, name: &str) -> &HeaderValues {
147 let name = HeaderName::from_str(name).expect("string slice needs to be valid ASCII");
148 self.get(name).expect("no entry found for name")
149 }
150}
151
152impl IntoIterator for Headers {
153 type Item = (HeaderName, HeaderValues);
154 type IntoIter = IntoIter;
155
156 #[inline]
158 fn into_iter(self) -> Self::IntoIter {
159 IntoIter {
160 inner: self.headers.into_iter(),
161 }
162 }
163}
164
165impl<'a> IntoIterator for &'a Headers {
166 type Item = (&'a HeaderName, &'a HeaderValues);
167 type IntoIter = Iter<'a>;
168
169 #[inline]
170 fn into_iter(self) -> Self::IntoIter {
171 self.iter()
172 }
173}
174
175impl<'a> IntoIterator for &'a mut Headers {
176 type Item = (&'a HeaderName, &'a mut HeaderValues);
177 type IntoIter = IterMut<'a>;
178
179 #[inline]
180 fn into_iter(self) -> Self::IntoIter {
181 self.iter_mut()
182 }
183}
184
185impl Debug for Headers {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.debug_map().entries(self.headers.iter()).finish()
188 }
189}
190
191impl AsRef<Headers> for Headers {
192 fn as_ref(&self) -> &Headers {
193 self
194 }
195}
196
197impl AsMut<Headers> for Headers {
198 fn as_mut(&mut self) -> &mut Headers {
199 self
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206 use std::str::FromStr;
207
208 const STATIC_HEADER: HeaderName = HeaderName::from_lowercase_str("hello");
209
210 #[test]
211 fn test_header_name_static_non_static() -> crate::Result<()> {
212 let static_header = HeaderName::from_lowercase_str("hello");
213 let non_static_header = HeaderName::from_str("hello")?;
214
215 let mut headers = Headers::new();
216 headers.append(STATIC_HEADER, "foo0").unwrap();
217 headers.append(static_header.clone(), "foo1").unwrap();
218 headers.append(non_static_header.clone(), "foo2").unwrap();
219
220 assert_eq!(headers[STATIC_HEADER], ["foo0", "foo1", "foo2",][..]);
221 assert_eq!(headers[static_header], ["foo0", "foo1", "foo2",][..]);
222 assert_eq!(headers[non_static_header], ["foo0", "foo1", "foo2",][..]);
223
224 Ok(())
225 }
226
227 #[test]
228 fn index_into_headers() {
229 let mut headers = Headers::new();
230 headers.insert("hello", "foo0").unwrap();
231 assert_eq!(headers["hello"], "foo0");
232 assert_eq!(headers.get("hello").unwrap(), "foo0");
233 }
234
235 #[test]
236 fn test_debug_single() {
237 let mut headers = Headers::new();
238 headers.insert("single", "foo0").unwrap();
239 assert_eq!(format!("{headers:?}"), r#"{"single": "foo0"}"#);
240 }
241
242 #[test]
243 fn test_debug_multiple() {
244 let mut headers = Headers::new();
245 headers.append("multi", "foo0").unwrap();
246 headers.append("multi", "foo1").unwrap();
247 assert_eq!(format!("{headers:?}"), r#"{"multi": ["foo0", "foo1"]}"#);
248 }
249}