1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use std::{
    borrow::Cow,
    collections::HashMap,
    fmt,
    hash::{Hash, Hasher},
    ops::Deref,
};

#[derive(Clone, Eq)]
pub struct HeaderName<'n>(Cow<'n, str>);

impl<'n> HeaderName<'n> {
    pub fn new(header_name: impl Into<Cow<'n, str>>) -> HeaderName<'n> {
        HeaderName(header_name.into())
    }
}

impl PartialEq for HeaderName<'_> {
    fn eq(&self, other: &Self) -> bool {
        self.as_ref().eq_ignore_ascii_case(other.as_ref())
    }
}

impl AsRef<str> for HeaderName<'_> {
    fn as_ref(&self) -> &str {
        self.0.as_ref()
    }
}

impl Deref for HeaderName<'_> {
    type Target = str;

    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}

impl<'n> Hash for HeaderName<'n> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.as_ref().to_uppercase().hash(state)
    }
}

impl<'n> From<&'n str> for HeaderName<'n> {
    fn from(s: &'n str) -> Self {
        HeaderName(s.into())
    }
}

impl From<String> for HeaderName<'_> {
    fn from(s: String) -> Self {
        HeaderName(s.into())
    }
}

impl<'n> From<Cow<'n, str>> for HeaderName<'n> {
    fn from(s: Cow<'n, str>) -> Self {
        HeaderName(s)
    }
}

impl fmt::Debug for HeaderName<'_> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

impl fmt::Display for HeaderName<'_> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

pub type HeaderValue<'v> = Cow<'v, str>;
pub type Headers<'h> = HashMap<HeaderName<'h>, HeaderValue<'h>>;

#[cfg(test)]
mod tests {
    use super::*;
    use std::{boxed::Box, error::Error, result::Result};

    #[test]
    fn test_header_name() -> Result<(), Box<dyn Error>> {
        let mut headers = Headers::new();
        headers.insert("Authorization".into(), "Test".into());
        assert_eq!(headers.get(&"authorization".into()), Some(&"Test".into()));
        assert_eq!(headers.get(&"AUTHORIZATION".into()), Some(&"Test".into()));
        Ok(())
    }
}