1use std::collections::{self, VecDeque, hash_map, hash_map::Entry};
2use std::fmt;
3
4use foldhash::fast::RandomState;
5
6use crate::{HeaderName, HeaderValue};
7
8type HashMap<K, V> = collections::HashMap<K, V, RandomState>;
9
10#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
12pub enum Either<A, B> {
13 Left(A),
15 Right(B),
17}
18
19#[derive(Clone, PartialEq, Eq)]
25pub struct HeaderMap {
26 pub(crate) inner: HashMap<HeaderName, Value>,
27}
28
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub enum Value {
31 One(HeaderValue),
32 Multi(VecDeque<HeaderValue>),
33}
34
35impl Value {
36 fn get(&self) -> &HeaderValue {
37 match self {
38 Value::One(val) => val,
39 Value::Multi(val) => &val[0],
40 }
41 }
42
43 fn get_mut(&mut self) -> &mut HeaderValue {
44 match self {
45 Value::One(val) => val,
46 Value::Multi(val) => &mut val[0],
47 }
48 }
49
50 pub(crate) fn append(&mut self, val: HeaderValue) {
51 *self = match std::mem::replace(self, Value::Multi(VecDeque::new())) {
52 Value::One(prev_val) => Value::Multi(VecDeque::from([prev_val, val])),
53 Value::Multi(mut vec) => {
54 vec.push_back(val);
55 Value::Multi(vec)
56 }
57 };
58 }
59}
60
61#[derive(Debug)]
62pub struct ValueIntoIter {
63 value: Value,
64}
65
66impl Iterator for ValueIntoIter {
67 type Item = HeaderValue;
68
69 fn next(&mut self) -> Option<Self::Item> {
70 match std::mem::replace(&mut self.value, Value::Multi(VecDeque::new())) {
71 Value::One(val) => Some(val),
72 Value::Multi(mut vec) => {
73 let val = vec.pop_front();
74 self.value = Value::Multi(vec);
75 val
76 }
77 }
78 }
79
80 fn size_hint(&self) -> (usize, Option<usize>) {
81 match self.value {
82 Value::One(_) => (1, Some(1)),
83 Value::Multi(ref v) => v.iter().size_hint(),
84 }
85 }
86}
87
88impl IntoIterator for Value {
89 type Item = HeaderValue;
90 type IntoIter = ValueIntoIter;
91
92 #[inline]
93 fn into_iter(self) -> Self::IntoIter {
94 ValueIntoIter { value: self }
95 }
96}
97
98impl Extend<HeaderValue> for Value {
99 #[inline]
100 fn extend<T>(&mut self, iter: T)
101 where
102 T: IntoIterator<Item = HeaderValue>,
103 {
104 for h in iter {
105 self.append(h);
106 }
107 }
108}
109
110impl From<HeaderValue> for Value {
111 #[inline]
112 fn from(hdr: HeaderValue) -> Value {
113 Value::One(hdr)
114 }
115}
116
117impl<'a> From<&'a HeaderValue> for Value {
118 #[inline]
119 fn from(hdr: &'a HeaderValue) -> Value {
120 Value::One(hdr.clone())
121 }
122}
123
124impl Default for HeaderMap {
125 #[inline]
126 fn default() -> Self {
127 Self::new()
128 }
129}
130
131impl HeaderMap {
132 pub fn new() -> Self {
137 HeaderMap {
138 inner: HashMap::default(),
139 }
140 }
141
142 pub fn with_capacity(capacity: usize) -> HeaderMap {
151 HeaderMap {
152 inner: HashMap::with_capacity_and_hasher(capacity, RandomState::default()),
153 }
154 }
155
156 pub fn len(&self) -> usize {
160 self.inner.len()
161 }
162
163 pub fn is_empty(&self) -> bool {
165 self.inner.len() == 0
166 }
167
168 pub fn clear(&mut self) {
171 self.inner.clear();
172 }
173
174 pub fn capacity(&self) -> usize {
179 self.inner.capacity()
180 }
181
182 pub fn reserve(&mut self, additional: usize) {
191 self.inner.reserve(additional);
192 }
193
194 pub fn get<N: AsName>(&self, name: N) -> Option<&HeaderValue> {
200 self.get2(name).map(Value::get)
201 }
202
203 fn get2<N: AsName>(&self, name: N) -> Option<&Value> {
204 match name.as_name() {
205 Either::Left(name) => self.inner.get(name),
206 Either::Right(s) => {
207 if let Ok(name) = HeaderName::try_from(s) {
208 self.inner.get(&name)
209 } else {
210 None
211 }
212 }
213 }
214 }
215
216 pub fn get_all<N: AsName>(&self, name: N) -> GetAll<'_> {
222 GetAll {
223 idx: 0,
224 item: self.get2(name),
225 }
226 }
227
228 pub fn get_mut<N: AsName>(&mut self, name: N) -> Option<&mut HeaderValue> {
234 match name.as_name() {
235 Either::Left(name) => self.inner.get_mut(name).map(Value::get_mut),
236 Either::Right(s) => {
237 if let Ok(name) = HeaderName::try_from(s) {
238 self.inner.get_mut(&name).map(Value::get_mut)
239 } else {
240 None
241 }
242 }
243 }
244 }
245
246 pub fn contains_key<N: AsName>(&self, key: N) -> bool {
248 match key.as_name() {
249 Either::Left(name) => self.inner.contains_key(name),
250 Either::Right(s) => {
251 if let Ok(name) = HeaderName::try_from(s) {
252 self.inner.contains_key(&name)
253 } else {
254 false
255 }
256 }
257 }
258 }
259
260 pub fn iter(&self) -> Iter<'_> {
265 Iter::new(self.inner.iter())
266 }
267
268 #[doc(hidden)]
269 pub fn iter_inner(&self) -> hash_map::Iter<'_, HeaderName, Value> {
270 self.inner.iter()
271 }
272
273 pub fn keys(&self) -> Keys<'_> {
278 Keys(self.inner.keys())
279 }
280
281 pub fn insert(&mut self, key: HeaderName, val: HeaderValue) {
288 let _ = self.inner.insert(key, Value::One(val));
289 }
290
291 pub fn append(&mut self, key: HeaderName, value: HeaderValue) {
296 match self.inner.entry(key) {
297 Entry::Occupied(mut entry) => entry.get_mut().append(value),
298 Entry::Vacant(entry) => {
299 entry.insert(Value::One(value));
300 }
301 }
302 }
303
304 pub fn remove<N: AsName>(&mut self, key: N) {
306 match key.as_name() {
307 Either::Left(name) => {
308 let _ = self.inner.remove(name);
309 }
310 Either::Right(s) => {
311 if let Ok(name) = HeaderName::try_from(s) {
312 let _ = self.inner.remove(&name);
313 }
314 }
315 }
316 }
317}
318
319#[doc(hidden)]
320pub trait AsName {
321 fn as_name(&self) -> Either<&HeaderName, &str>;
322}
323
324impl AsName for HeaderName {
325 fn as_name(&self) -> Either<&HeaderName, &str> {
326 Either::Left(self)
327 }
328}
329
330impl AsName for &HeaderName {
331 fn as_name(&self) -> Either<&HeaderName, &str> {
332 Either::Left(self)
333 }
334}
335
336impl AsName for &str {
337 fn as_name(&self) -> Either<&HeaderName, &str> {
338 Either::Right(self)
339 }
340}
341
342impl AsName for String {
343 fn as_name(&self) -> Either<&HeaderName, &str> {
344 Either::Right(self.as_str())
345 }
346}
347
348impl AsName for &String {
349 fn as_name(&self) -> Either<&HeaderName, &str> {
350 Either::Right(self.as_str())
351 }
352}
353
354#[derive(Debug)]
355pub struct GetAll<'a> {
356 idx: usize,
357 item: Option<&'a Value>,
358}
359
360impl<'a> Iterator for GetAll<'a> {
361 type Item = &'a HeaderValue;
362
363 #[inline]
364 fn next(&mut self) -> Option<&'a HeaderValue> {
365 if let Some(ref val) = self.item {
366 match val {
367 Value::One(val) => {
368 self.item.take();
369 Some(val)
370 }
371 Value::Multi(vec) => {
372 if self.idx < vec.len() {
373 let item = Some(&vec[self.idx]);
374 self.idx += 1;
375 item
376 } else {
377 self.item.take();
378 None
379 }
380 }
381 }
382 } else {
383 None
384 }
385 }
386}
387
388#[derive(Debug)]
389pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>);
390
391impl<'a> Iterator for Keys<'a> {
392 type Item = &'a HeaderName;
393
394 #[inline]
395 fn next(&mut self) -> Option<&'a HeaderName> {
396 self.0.next()
397 }
398}
399
400impl<'a> IntoIterator for &'a HeaderMap {
401 type Item = (&'a HeaderName, &'a HeaderValue);
402 type IntoIter = Iter<'a>;
403
404 fn into_iter(self) -> Self::IntoIter {
405 self.iter()
406 }
407}
408
409#[derive(Debug)]
410pub struct Iter<'a> {
411 idx: usize,
412 current: Option<(&'a HeaderName, &'a VecDeque<HeaderValue>)>,
413 inner: hash_map::Iter<'a, HeaderName, Value>,
414}
415
416impl<'a> Iter<'a> {
417 fn new(inner: hash_map::Iter<'a, HeaderName, Value>) -> Self {
418 Self {
419 inner,
420 idx: 0,
421 current: None,
422 }
423 }
424}
425
426impl<'a> Iterator for Iter<'a> {
427 type Item = (&'a HeaderName, &'a HeaderValue);
428
429 #[inline]
430 fn next(&mut self) -> Option<(&'a HeaderName, &'a HeaderValue)> {
431 if let Some(ref mut item) = self.current {
432 if self.idx < item.1.len() {
433 let item = (item.0, &item.1[self.idx]);
434 self.idx += 1;
435 return Some(item);
436 }
437 self.idx = 0;
438 self.current.take();
439 }
440 if let Some(item) = self.inner.next() {
441 match item.1 {
442 Value::One(value) => Some((item.0, value)),
443 Value::Multi(vec) => {
444 self.current = Some((item.0, vec));
445 self.next()
446 }
447 }
448 } else {
449 None
450 }
451 }
452}
453
454impl fmt::Debug for HeaderMap {
455 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456 let mut f = f.debug_map();
457
458 for (key, val) in &self.inner {
459 match val {
460 Value::One(val) => {
461 let _ = f.entry(&key, &val);
462 }
463 Value::Multi(val) => {
464 for v in val {
465 f.entry(&key, &v);
466 }
467 }
468 }
469 }
470 f.finish()
471 }
472}
473
474#[cfg(test)]
475mod tests {
476 use super::*;
477 use crate::header::{ACCEPT_ENCODING, CONTENT_TYPE};
478
479 #[test]
480 #[allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args)]
481 fn test_basics() {
482 let m = HeaderMap::default();
483 assert!(m.is_empty());
484 let mut m = HeaderMap::with_capacity(10);
485 assert!(m.is_empty());
486 assert!(m.capacity() >= 10);
487 m.reserve(20);
488 assert!(m.capacity() >= 20);
489
490 m.insert(CONTENT_TYPE, HeaderValue::from_static("text"));
491 assert!(m.contains_key(CONTENT_TYPE));
492 assert!(m.contains_key("content-type"));
493 assert!(m.contains_key("content-type".to_string()));
494 assert!(m.contains_key(&("content-type".to_string())));
495 assert_eq!(
496 *m.get_mut("content-type").unwrap(),
497 HeaderValue::from_static("text")
498 );
499 assert_eq!(
500 *m.get_mut(CONTENT_TYPE).unwrap(),
501 HeaderValue::from_static("text")
502 );
503 assert!(format!("{m:?}").contains("content-type"));
504
505 assert!(m.keys().any(|x| x == CONTENT_TYPE));
506 m.remove("content-type");
507 assert!(m.is_empty());
508 }
509
510 #[test]
511 fn test_append() {
512 let mut map = HeaderMap::new();
513
514 map.append(ACCEPT_ENCODING, HeaderValue::from_static("gzip"));
515 assert_eq!(
516 map.get_all(ACCEPT_ENCODING).collect::<Vec<_>>(),
517 vec![&HeaderValue::from_static("gzip"),]
518 );
519
520 map.append(ACCEPT_ENCODING, HeaderValue::from_static("br"));
521 map.append(ACCEPT_ENCODING, HeaderValue::from_static("deflate"));
522 assert_eq!(
523 map.get_all(ACCEPT_ENCODING).collect::<Vec<_>>(),
524 vec![
525 &HeaderValue::from_static("gzip"),
526 &HeaderValue::from_static("br"),
527 &HeaderValue::from_static("deflate"),
528 ]
529 );
530 assert_eq!(
531 map.get(ACCEPT_ENCODING),
532 Some(&HeaderValue::from_static("gzip"))
533 );
534 assert_eq!(
535 map.get_mut(ACCEPT_ENCODING),
536 Some(&mut HeaderValue::from_static("gzip"))
537 );
538
539 map.remove(ACCEPT_ENCODING);
540 assert_eq!(map.get(ACCEPT_ENCODING), None);
541 }
542
543 #[test]
544 fn test_from_http() {
545 let mut map = http::HeaderMap::new();
546 map.append(ACCEPT_ENCODING, http::HeaderValue::from_static("gzip"));
547
548 let map2 = HeaderMap::from(map);
549 assert_eq!(
550 map2.get(ACCEPT_ENCODING),
551 Some(&HeaderValue::from_static("gzip"))
552 );
553 }
554
555 #[test]
556 fn value_into_iter() {
557 let mut it = Value::One(HeaderValue::from_static("a")).into_iter();
558 assert_eq!(it.size_hint(), (1, Some(1)));
559 assert_eq!(it.next(), Some(HeaderValue::from_static("a")));
560 assert_eq!(it.size_hint(), (0, Some(0)));
561 assert_eq!(it.next(), None);
562
563 let mut val = Value::One(HeaderValue::from_static("a"));
564 val.append(HeaderValue::from_static("b"));
565 val.append(HeaderValue::from_static("c"));
566 let mut it = val.into_iter();
567 assert_eq!(it.size_hint(), (3, Some(3)));
568 assert_eq!(it.next(), Some(HeaderValue::from_static("a")));
569 assert_eq!(it.next(), Some(HeaderValue::from_static("b")));
570 assert_eq!(it.size_hint(), (1, Some(1)));
571 assert_eq!(it.next(), Some(HeaderValue::from_static("c")));
572 assert_eq!(it.next(), None);
573 assert_eq!(it.next(), None);
574 }
575}