http_types_rs/headers/
header.rs

1use std::ops::Deref;
2
3use crate::headers::{HeaderName, HeaderValue, Headers};
4
5/// A trait representing a [`HeaderName`] and [`HeaderValue`] pair.
6pub trait Header {
7    /// Access the header's name.
8    fn header_name(&self) -> HeaderName;
9
10    /// Access the header's value.
11    fn header_value(&self) -> HeaderValue;
12
13    /// Insert the header name and header value into something that looks like a
14    /// [`Headers`] map.
15    fn apply_header<H: AsMut<Headers>>(&self, mut headers: H) {
16        let name = self.header_name();
17        let value = self.header_value();
18
19        // The value should already have been validated when it was created, so this should
20        // possibly be done with an unsafe call
21        headers.as_mut().insert(name, value).unwrap();
22    }
23}
24
25impl<'a, 'b> Header for (&'a str, &'b str) {
26    fn header_name(&self) -> HeaderName {
27        HeaderName::from(self.0)
28    }
29
30    fn header_value(&self) -> HeaderValue {
31        HeaderValue::from_bytes(self.1.to_owned().into_bytes()).expect("String slice should be valid ASCII")
32    }
33}
34
35impl<'a, T: Header> Header for &'a T {
36    #[allow(suspicious_double_ref_op)]
37    fn header_name(&self) -> HeaderName {
38        self.deref().header_name()
39    }
40
41    #[allow(suspicious_double_ref_op)]
42    fn header_value(&self) -> HeaderValue {
43        self.deref().header_value()
44    }
45}
46
47#[cfg(test)]
48mod test {
49    use super::*;
50
51    #[test]
52    fn header_from_strings() {
53        let strings = ("Content-Length", "12");
54        assert_eq!(strings.header_name(), "Content-Length");
55        assert_eq!(strings.header_value(), "12");
56    }
57}