http_types/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 ) -> Option<HeaderValues> {
53 let name = name.into();
54 let values: HeaderValues = values.to_header_values().unwrap().collect();
55 self.headers.insert(name, values)
56 }
57
58 pub fn append(&mut self, name: impl Into<HeaderName>, values: impl ToHeaderValues) {
63 let name = name.into();
64 match self.get_mut(&name) {
65 Some(headers) => {
66 let mut values: HeaderValues = values.to_header_values().unwrap().collect();
67 headers.append(&mut values);
68 }
69 None => {
70 self.insert(name, values);
71 }
72 }
73 }
74
75 pub fn get(&self, name: impl Into<HeaderName>) -> Option<&HeaderValues> {
77 self.headers.get(&name.into())
78 }
79
80 pub fn get_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValues> {
82 self.headers.get_mut(&name.into())
83 }
84
85 pub fn remove(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValues> {
87 self.headers.remove(&name.into())
88 }
89
90 pub fn iter(&self) -> Iter<'_> {
92 Iter {
93 inner: self.headers.iter(),
94 }
95 }
96
97 pub fn iter_mut(&mut self) -> IterMut<'_> {
100 IterMut {
101 inner: self.headers.iter_mut(),
102 }
103 }
104
105 pub fn names(&self) -> Names<'_> {
107 Names {
108 inner: self.headers.keys(),
109 }
110 }
111
112 pub fn values(&self) -> Values<'_> {
114 Values::new(self.headers.values())
115 }
116}
117
118impl Index<HeaderName> for Headers {
119 type Output = HeaderValues;
120
121 #[inline]
127 fn index(&self, name: HeaderName) -> &HeaderValues {
128 self.get(name).expect("no entry found for name")
129 }
130}
131
132impl Index<&str> for Headers {
133 type Output = HeaderValues;
134
135 #[inline]
141 fn index(&self, name: &str) -> &HeaderValues {
142 let name = HeaderName::from_str(name).expect("string slice needs to be valid ASCII");
143 self.get(name).expect("no entry found for name")
144 }
145}
146
147impl IntoIterator for Headers {
148 type Item = (HeaderName, HeaderValues);
149 type IntoIter = IntoIter;
150
151 #[inline]
153 fn into_iter(self) -> Self::IntoIter {
154 IntoIter {
155 inner: self.headers.into_iter(),
156 }
157 }
158}
159
160impl<'a> IntoIterator for &'a Headers {
161 type Item = (&'a HeaderName, &'a HeaderValues);
162 type IntoIter = Iter<'a>;
163
164 #[inline]
165 fn into_iter(self) -> Self::IntoIter {
166 self.iter()
167 }
168}
169
170impl<'a> IntoIterator for &'a mut Headers {
171 type Item = (&'a HeaderName, &'a mut HeaderValues);
172 type IntoIter = IterMut<'a>;
173
174 #[inline]
175 fn into_iter(self) -> Self::IntoIter {
176 self.iter_mut()
177 }
178}
179
180impl Debug for Headers {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 f.debug_map().entries(self.headers.iter()).finish()
183 }
184}
185
186impl AsRef<Headers> for Headers {
187 fn as_ref(&self) -> &Headers {
188 self
189 }
190}
191
192impl AsMut<Headers> for Headers {
193 fn as_mut(&mut self) -> &mut Headers {
194 self
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201 use std::str::FromStr;
202
203 const STATIC_HEADER: HeaderName = HeaderName::from_lowercase_str("hello");
204
205 #[test]
206 fn test_header_name_static_non_static() -> crate::Result<()> {
207 let static_header = HeaderName::from_lowercase_str("hello");
208 let non_static_header = HeaderName::from_str("hello")?;
209
210 let mut headers = Headers::new();
211 headers.append(STATIC_HEADER, "foo0");
212 headers.append(static_header.clone(), "foo1");
213 headers.append(non_static_header.clone(), "foo2");
214
215 assert_eq!(headers[STATIC_HEADER], ["foo0", "foo1", "foo2",][..]);
216 assert_eq!(headers[static_header], ["foo0", "foo1", "foo2",][..]);
217 assert_eq!(headers[non_static_header], ["foo0", "foo1", "foo2",][..]);
218
219 Ok(())
220 }
221
222 #[test]
223 fn index_into_headers() {
224 let mut headers = Headers::new();
225 headers.insert("hello", "foo0");
226 assert_eq!(headers["hello"], "foo0");
227 assert_eq!(headers.get("hello").unwrap(), "foo0");
228 }
229
230 #[test]
231 fn test_debug_single() {
232 let mut headers = Headers::new();
233 headers.insert("single", "foo0");
234 assert_eq!(format!("{:?}", headers), r#"{"single": "foo0"}"#);
235 }
236
237 #[test]
238 fn test_debug_multiple() {
239 let mut headers = Headers::new();
240 headers.append("multi", "foo0");
241 headers.append("multi", "foo1");
242 assert_eq!(format!("{:?}", headers), r#"{"multi": ["foo0", "foo1"]}"#);
243 }
244}