snx/http/
header.rs

1use std::{collections::HashMap, ops::Deref};
2
3/// A multimap of HTTP headers to values.
4///
5/// Header names are case-insensitive.
6#[derive(Clone, Default, Debug)]
7pub struct HeaderMap(HashMap<String, Vec<String>>);
8
9impl HeaderMap {
10    /// Creates a new header map.
11    pub fn new() -> Self {
12        Self::default()
13    }
14
15    /// Inserts a header.
16    ///
17    /// ```
18    /// use snx::HeaderMap;
19    ///
20    /// let mut headers = HeaderMap::new();
21    /// headers.insert("Content-Type", "application/json");
22    /// ```
23    pub fn insert(&mut self, name: &str, value: &str) {
24        match self.0.get_mut(name) {
25            Some(values) => values.push(value.to_string()),
26            None => {
27                self.0.insert(name.to_lowercase(), vec![value.to_string()]);
28            }
29        }
30    }
31
32    /// Gets the first value of a header if it exists.
33    ///
34    /// ```
35    /// use snx::HeaderMap;
36    ///
37    /// let mut headers = HeaderMap::new();
38    /// headers.insert("Content-Type", "application/json");
39    ///
40    /// let content_type = headers.get("Content-Type").unwrap();
41    /// ```
42    pub fn get(&self, name: &str) -> Option<String> {
43        self.0.get(&name.to_lowercase())?.first().cloned()
44    }
45
46    /// Gets all values of a header.
47    ///
48    /// ```
49    /// use snx::HeaderMap;
50    ///
51    /// let mut headers = HeaderMap::new();
52    /// headers.insert("Transfer-Encoding", "chunked");
53    /// headers.insert("Transfer-Encoding", "gzip");
54    ///
55    /// let encodings = headers.get_all("Transfer-Encoding").unwrap();
56    /// ```
57    pub fn get_all(&self, name: &str) -> Option<Vec<String>> {
58        self.0.get(&name.to_lowercase()).cloned()
59    }
60}
61
62impl From<(&str, &str)> for HeaderMap {
63    fn from(val: (&str, &str)) -> Self {
64        let mut map = HeaderMap::new();
65
66        map.insert(&val.0.to_lowercase(), val.1);
67
68        map
69    }
70}
71
72impl Deref for HeaderMap {
73    type Target = HashMap<String, Vec<String>>;
74
75    fn deref(&self) -> &Self::Target {
76        &self.0
77    }
78}