1use crate::name::HeaderName;
10use crate::value::HeaderValue;
11use serde::de::{self, MapAccess, SeqAccess, Visitor};
12use serde::ser::{SerializeMap, Serializer};
13use serde::{Deserialize, Deserializer, Serialize};
14use std::borrow::Cow;
15use std::fmt;
16
17pub trait AsHeaderName {
23 fn as_lower(&self) -> Cow<'_, str>;
26}
27
28impl AsHeaderName for HeaderName {
29 fn as_lower(&self) -> Cow<'_, str> {
30 Cow::Borrowed(self.as_str())
31 }
32}
33
34impl AsHeaderName for &HeaderName {
35 fn as_lower(&self) -> Cow<'_, str> {
36 Cow::Borrowed(self.as_str())
37 }
38}
39
40impl AsHeaderName for str {
41 fn as_lower(&self) -> Cow<'_, str> {
42 if self.bytes().all(|b| !b.is_ascii_uppercase()) {
43 Cow::Borrowed(self)
44 } else {
45 Cow::Owned(self.to_ascii_lowercase())
46 }
47 }
48}
49
50impl AsHeaderName for &str {
51 fn as_lower(&self) -> Cow<'_, str> {
52 <str as AsHeaderName>::as_lower(self)
53 }
54}
55
56impl AsHeaderName for String {
57 fn as_lower(&self) -> Cow<'_, str> {
58 <str as AsHeaderName>::as_lower(self.as_str())
59 }
60}
61
62impl AsHeaderName for &String {
63 fn as_lower(&self) -> Cow<'_, str> {
64 <str as AsHeaderName>::as_lower(self.as_str())
65 }
66}
67
68#[derive(Debug, Clone, Default, PartialEq, Eq)]
70pub struct HeaderMap {
71 entries: Vec<(HeaderName, HeaderValue)>,
72}
73
74impl HeaderMap {
75 pub fn new() -> Self {
77 Self { entries: Vec::new() }
78 }
79
80 pub fn with_capacity(n: usize) -> Self {
82 Self {
83 entries: Vec::with_capacity(n),
84 }
85 }
86
87 pub fn append(&mut self, name: impl Into<HeaderName>, value: impl Into<HeaderValue>) {
92 self.entries.push((name.into(), value.into()));
93 }
94
95 pub fn insert(&mut self, name: impl Into<HeaderName>, value: impl Into<HeaderValue>) {
102 let name = name.into();
103 let value = value.into();
104 let mut first = None;
105 let mut i = 0;
106 while i < self.entries.len() {
107 if self.entries[i].0 == name {
108 if first.is_none() {
109 first = Some(i);
110 self.entries[i].1 = value.clone();
111 i += 1;
112 } else {
113 self.entries.remove(i);
114 }
115 } else {
116 i += 1;
117 }
118 }
119 if first.is_none() {
120 self.entries.push((name, value));
121 }
122 }
123
124 pub fn remove<N: AsHeaderName>(&mut self, name: N) -> usize {
126 let lower = name.as_lower();
127 let before = self.entries.len();
128 self.entries.retain(|(n, _)| n.as_str() != lower.as_ref());
129 before - self.entries.len()
130 }
131
132 pub fn get<N: AsHeaderName>(&self, name: N) -> Option<&HeaderValue> {
134 let lower = name.as_lower();
135 self
136 .entries
137 .iter()
138 .find(|(n, _)| n.as_str() == lower.as_ref())
139 .map(|(_, v)| v)
140 }
141
142 pub fn get_all<N: AsHeaderName>(&self, name: N) -> impl Iterator<Item = &HeaderValue> {
144 let lower = name.as_lower().into_owned();
145 self
146 .entries
147 .iter()
148 .filter(move |(n, _)| n.as_str() == lower.as_str())
149 .map(|(_, v)| v)
150 }
151
152 pub fn contains_key<N: AsHeaderName>(&self, name: N) -> bool {
154 let lower = name.as_lower();
155 self.entries.iter().any(|(n, _)| n.as_str() == lower.as_ref())
156 }
157
158 pub fn iter(&self) -> impl Iterator<Item = (&HeaderName, &HeaderValue)> {
160 self.entries.iter().map(|(n, v)| (n, v))
161 }
162
163 pub fn len(&self) -> usize {
165 self.entries.len()
166 }
167
168 pub fn is_empty(&self) -> bool {
170 self.entries.is_empty()
171 }
172
173 pub fn extend(&mut self, other: HeaderMap) {
176 self.entries.extend(other.entries);
177 }
178
179 pub fn merge_replacing(&mut self, other: HeaderMap) {
182 for (name, value) in &other.entries {
183 self.entries.retain(|(n, _)| n != name);
184 let _ = value;
185 }
186 self.entries.extend(other.entries);
187 }
188}
189
190impl FromIterator<(HeaderName, HeaderValue)> for HeaderMap {
191 fn from_iter<I: IntoIterator<Item = (HeaderName, HeaderValue)>>(iter: I) -> Self {
192 Self {
193 entries: iter.into_iter().collect(),
194 }
195 }
196}
197
198impl IntoIterator for HeaderMap {
199 type Item = (HeaderName, HeaderValue);
200 type IntoIter = std::vec::IntoIter<Self::Item>;
201 fn into_iter(self) -> Self::IntoIter {
202 self.entries.into_iter()
203 }
204}
205
206impl<'a> IntoIterator for &'a HeaderMap {
207 type Item = (&'a HeaderName, &'a HeaderValue);
208 type IntoIter = std::iter::Map<
209 std::slice::Iter<'a, (HeaderName, HeaderValue)>,
210 fn(&'a (HeaderName, HeaderValue)) -> (&'a HeaderName, &'a HeaderValue),
211 >;
212 fn into_iter(self) -> Self::IntoIter {
213 self.entries.iter().map(|(n, v)| (n, v))
214 }
215}
216
217impl Serialize for HeaderMap {
228 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
229 let mut grouped: Vec<(&HeaderName, Vec<&HeaderValue>)> = Vec::with_capacity(self.entries.len());
231 'outer: for (n, v) in &self.entries {
232 for (existing_name, vs) in grouped.iter_mut() {
233 if *existing_name == n {
234 vs.push(v);
235 continue 'outer;
236 }
237 }
238 grouped.push((n, vec![v]));
239 }
240 let mut map = serializer.serialize_map(Some(grouped.len()))?;
241 for (name, vals) in grouped {
242 if vals.len() == 1 {
243 map.serialize_entry(name, vals[0])?;
244 } else {
245 map.serialize_entry(name, &vals)?;
246 }
247 }
248 map.end()
249 }
250}
251
252struct StringOrSeq;
255
256impl<'de> Visitor<'de> for StringOrSeq {
257 type Value = Vec<String>;
258
259 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
260 f.write_str("a string or array of strings")
261 }
262
263 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
264 Ok(vec![v.to_string()])
265 }
266
267 fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
268 Ok(vec![v])
269 }
270
271 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
272 let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
273 while let Some(s) = seq.next_element::<String>()? {
274 out.push(s);
275 }
276 Ok(out)
277 }
278}
279
280#[derive(Default)]
281struct HeaderMapVisitor;
282
283impl<'de> Visitor<'de> for HeaderMapVisitor {
284 type Value = HeaderMap;
285
286 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
287 f.write_str("a map of header name to string or array of strings")
288 }
289
290 fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
291 let mut out = HeaderMap::with_capacity(access.size_hint().unwrap_or(0));
292 while let Some(name) = access.next_key::<HeaderName>()? {
293 let values = access.next_value_seed(StringOrSeqSeed)?;
294 for v in values {
295 out.append(name.clone(), HeaderValue::from_string(v));
296 }
297 }
298 Ok(out)
299 }
300}
301
302struct StringOrSeqSeed;
303
304impl<'de> de::DeserializeSeed<'de> for StringOrSeqSeed {
305 type Value = Vec<String>;
306 fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
307 deserializer.deserialize_any(StringOrSeq)
308 }
309}
310
311impl<'de> Deserialize<'de> for HeaderMap {
312 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
313 deserializer.deserialize_map(HeaderMapVisitor)
314 }
315}
316
317#[cfg(test)]
318mod tests {
319 use super::*;
320
321 fn name(s: &'static str) -> HeaderName {
322 HeaderName::new(s)
323 }
324
325 #[test]
326 fn insert_preserves_order_and_case() {
327 let mut m = HeaderMap::new();
328 m.insert(name("X-Aaa"), "1");
329 m.insert(name("Authorization"), "Bearer x");
330 m.insert(name("Content-Type"), "application/json");
331 let collected: Vec<_> = m
332 .iter()
333 .map(|(n, v)| (n.original().to_string(), v.as_str().to_string()))
334 .collect();
335 assert_eq!(
336 collected,
337 vec![
338 ("X-Aaa".into(), "1".into()),
339 ("Authorization".into(), "Bearer x".into()),
340 ("Content-Type".into(), "application/json".into()),
341 ]
342 );
343 }
344
345 #[test]
346 fn get_is_case_insensitive() {
347 let mut m = HeaderMap::new();
348 m.insert(name("Authorization"), "Bearer x");
349 assert_eq!(m.get(name("authorization")).map(|v| v.as_str()), Some("Bearer x"));
350 assert_eq!(m.get(name("AUTHORIZATION")).map(|v| v.as_str()), Some("Bearer x"));
351 }
352
353 #[test]
354 fn duplicates_preserved() {
355 let mut m = HeaderMap::new();
356 m.append(name("Set-Cookie"), "a=1");
357 m.append(name("Set-Cookie"), "b=2");
358 let all: Vec<_> = m.get_all(&name("set-cookie")).map(|v| v.as_str().to_string()).collect();
359 assert_eq!(all, vec!["a=1", "b=2"]);
360 assert_eq!(m.len(), 2);
361 }
362
363 #[test]
364 fn insert_overrides_existing_value() {
365 let mut m = HeaderMap::new();
366 m.insert(name("Authorization"), "Bearer old");
367 m.insert(name("authorization"), "Bearer new");
368 assert_eq!(m.len(), 1);
369 assert_eq!(m.get(name("authorization")).map(|v| v.as_str()), Some("Bearer new"));
370 }
371
372 #[test]
373 fn insert_removes_duplicates_keeps_position() {
374 let mut m = HeaderMap::new();
375 m.insert(name("A"), "1");
376 m.append(name("Set-Cookie"), "old1");
377 m.insert(name("B"), "2");
378 m.append(name("Set-Cookie"), "old2");
379 m.insert(name("set-cookie"), "new");
380 let collected: Vec<_> = m
381 .iter()
382 .map(|(n, v)| (n.original().to_string(), v.as_str().to_string()))
383 .collect();
384 assert_eq!(
385 collected,
386 vec![
387 ("A".into(), "1".into()),
388 ("Set-Cookie".into(), "new".into()),
389 ("B".into(), "2".into()),
390 ]
391 );
392 }
393
394 #[test]
395 fn remove_returns_count() {
396 let mut m = HeaderMap::new();
397 m.append(name("X"), "1");
398 m.append(name("X"), "2");
399 m.insert(name("Y"), "3");
400 assert_eq!(m.remove(name("x")), 2);
401 assert_eq!(m.len(), 1);
402 }
403
404 #[test]
405 fn extend_keeps_duplicates() {
406 let mut a = HeaderMap::new();
407 a.append(name("X"), "1");
408 let mut b = HeaderMap::new();
409 b.append(name("X"), "2");
410 a.extend(b);
411 assert_eq!(a.len(), 2);
412 }
413
414 #[test]
415 fn merge_replacing_overrides_existing() {
416 let mut a = HeaderMap::new();
417 a.insert(name("X"), "old");
418 a.insert(name("Y"), "keep");
419 let mut b = HeaderMap::new();
420 b.insert(name("x"), "new");
421 a.merge_replacing(b);
422 let collected: Vec<_> = a
423 .iter()
424 .map(|(n, v)| (n.original().to_string(), v.as_str().to_string()))
425 .collect();
426 assert_eq!(collected, vec![("Y".into(), "keep".into()), ("x".into(), "new".into())]);
427 }
428
429 #[test]
430 fn ref_into_iter_yields_borrowed_pairs() {
431 let mut m = HeaderMap::new();
432 m.insert(name("A"), "1");
433 m.insert(name("B"), "2");
434 let collected: Vec<_> = (&m).into_iter().map(|(n, v)| (n.as_str(), v.as_str())).collect();
435 assert_eq!(collected, vec![("a", "1"), ("b", "2")]);
436 }
437
438 #[test]
439 fn serde_round_trip_preserves_case_and_duplicates() {
440 let mut m = HeaderMap::new();
441 m.insert(name("Authorization"), "Bearer x");
442 m.append(name("Set-Cookie"), "a=1");
443 m.append(name("Set-Cookie"), "b=2");
444 m.insert(name("Content-Type"), "application/json");
445 let json = serde_json::to_string(&m).unwrap();
446 assert!(json.contains("\"Authorization\":\"Bearer x\""), "got {json}");
447 assert!(json.contains("\"Set-Cookie\":[\"a=1\",\"b=2\"]"), "got {json}");
448 let back: HeaderMap = serde_json::from_str(&json).unwrap();
449 assert_eq!(back.len(), 4);
450 assert_eq!(back.get(name("authorization")).unwrap().as_str(), "Bearer x");
451 let cookie_name = name("set-cookie");
452 let cookies: Vec<_> = back.get_all(&cookie_name).map(|v| v.as_str()).collect();
453 assert_eq!(cookies, vec!["a=1", "b=2"]);
454 }
455
456 #[test]
457 fn serde_deserialize_accepts_legacy_string_only_object() {
458 let json = r#"{"authorization":"Bearer x","content-type":"application/json"}"#;
460 let m: HeaderMap = serde_json::from_str(json).unwrap();
461 assert_eq!(m.len(), 2);
462 assert_eq!(m.get(name("Authorization")).unwrap().as_str(), "Bearer x");
463 }
464
465 #[test]
466 fn serde_deserialize_accepts_array_value() {
467 let json = r#"{"X-Foo":["a","b","c"]}"#;
468 let m: HeaderMap = serde_json::from_str(json).unwrap();
469 assert_eq!(m.len(), 3);
470 let foo = name("x-foo");
471 let vals: Vec<_> = m.get_all(&foo).map(|v| v.as_str()).collect();
472 assert_eq!(vals, vec!["a", "b", "c"]);
473 }
474}