http_types_rs/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::{HeaderName, HeaderValues, IntoIter, Iter, IterMut, Names, ToHeaderValues, Values};
11
12#[derive(Clone)]
29pub struct Headers {
30 pub(crate) headers: HashMap<HeaderName, HeaderValues>,
31}
32
33impl Headers {
34 pub fn new() -> Self {
36 Self { headers: HashMap::new() }
37 }
38
39 pub fn insert(&mut self, name: impl Into<HeaderName>, values: impl ToHeaderValues) -> crate::Result<Option<HeaderValues>> {
45 let name = name.into();
46 let values: HeaderValues = values.to_header_values()?.collect();
47 Ok(self.headers.insert(name, values))
48 }
49
50 pub fn append(&mut self, name: impl Into<HeaderName>, values: impl ToHeaderValues) -> crate::Result<()> {
55 let name = name.into();
56 match self.get_mut(&name) {
57 Some(headers) => {
58 let mut values: HeaderValues = values.to_header_values()?.collect();
59 headers.append(&mut values);
60 }
61 None => {
62 self.insert(name, values)?;
63 }
64 }
65 Ok(())
66 }
67
68 pub fn get(&self, name: impl Into<HeaderName>) -> Option<&HeaderValues> {
70 self.headers.get(&name.into())
71 }
72
73 pub fn get_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValues> {
75 self.headers.get_mut(&name.into())
76 }
77
78 pub fn remove(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValues> {
80 self.headers.remove(&name.into())
81 }
82
83 pub fn iter(&self) -> Iter<'_> {
85 Iter { inner: self.headers.iter() }
86 }
87
88 pub fn iter_mut(&mut self) -> IterMut<'_> {
91 IterMut {
92 inner: self.headers.iter_mut(),
93 }
94 }
95
96 pub fn names(&self) -> Names<'_> {
98 Names { inner: self.headers.keys() }
99 }
100
101 pub fn values(&self) -> Values<'_> {
103 Values::new(self.headers.values())
104 }
105}
106
107impl Index<HeaderName> for Headers {
108 type Output = HeaderValues;
109
110 #[inline]
116 fn index(&self, name: HeaderName) -> &HeaderValues {
117 self.get(name).expect("no entry found for name")
118 }
119}
120
121impl Index<&str> for Headers {
122 type Output = HeaderValues;
123
124 #[inline]
130 fn index(&self, name: &str) -> &HeaderValues {
131 let name = HeaderName::from_str(name).expect("string slice needs to be valid ASCII");
132 self.get(name).expect("no entry found for name")
133 }
134}
135
136impl IntoIterator for Headers {
137 type Item = (HeaderName, HeaderValues);
138 type IntoIter = IntoIter;
139
140 #[inline]
142 fn into_iter(self) -> Self::IntoIter {
143 IntoIter {
144 inner: self.headers.into_iter(),
145 }
146 }
147}
148
149impl<'a> IntoIterator for &'a Headers {
150 type Item = (&'a HeaderName, &'a HeaderValues);
151 type IntoIter = Iter<'a>;
152
153 #[inline]
154 fn into_iter(self) -> Self::IntoIter {
155 self.iter()
156 }
157}
158
159impl<'a> IntoIterator for &'a mut Headers {
160 type Item = (&'a HeaderName, &'a mut HeaderValues);
161 type IntoIter = IterMut<'a>;
162
163 #[inline]
164 fn into_iter(self) -> Self::IntoIter {
165 self.iter_mut()
166 }
167}
168
169impl Debug for Headers {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 f.debug_map().entries(self.headers.iter()).finish()
172 }
173}
174
175impl AsRef<Headers> for Headers {
176 fn as_ref(&self) -> &Headers {
177 self
178 }
179}
180
181impl AsMut<Headers> for Headers {
182 fn as_mut(&mut self) -> &mut Headers {
183 self
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use super::*;
190 use std::str::FromStr;
191
192 const STATIC_HEADER: HeaderName = HeaderName::from_lowercase_str("hello");
193
194 #[test]
195 fn test_header_name_static_non_static() -> crate::Result<()> {
196 let static_header = HeaderName::from_lowercase_str("hello");
197 let non_static_header = HeaderName::from_str("hello")?;
198
199 let mut headers = Headers::new();
200 headers.append(STATIC_HEADER, "foo0").unwrap();
201 headers.append(static_header.clone(), "foo1").unwrap();
202 headers.append(non_static_header.clone(), "foo2").unwrap();
203
204 assert_eq!(headers[STATIC_HEADER], ["foo0", "foo1", "foo2",][..]);
205 assert_eq!(headers[static_header], ["foo0", "foo1", "foo2",][..]);
206 assert_eq!(headers[non_static_header], ["foo0", "foo1", "foo2",][..]);
207
208 Ok(())
209 }
210
211 #[test]
212 fn index_into_headers() {
213 let mut headers = Headers::new();
214 headers.insert("hello", "foo0").unwrap();
215 assert_eq!(headers["hello"], "foo0");
216 assert_eq!(headers.get("hello").unwrap(), "foo0");
217 }
218
219 #[test]
220 fn test_debug_single() {
221 let mut headers = Headers::new();
222 headers.insert("single", "foo0").unwrap();
223 assert_eq!(format!("{:?}", headers), r#"{"single": "foo0"}"#);
224 }
225
226 #[test]
227 fn test_debug_multiple() {
228 let mut headers = Headers::new();
229 headers.append("multi", "foo0").unwrap();
230 headers.append("multi", "foo1").unwrap();
231 assert_eq!(format!("{:?}", headers), r#"{"multi": ["foo0", "foo1"]}"#);
232 }
233}