Skip to main content

tower_embed_core/
headers.rs

1//! Typed HTTP headers to be used with [`http`] crate.
2//!
3//! [`http`]: https://docs.rs/http
4
5pub use self::{
6    content_type::ContentType, etag::ETag, if_modified_since::IfModifiedSince,
7    if_none_match::IfNoneMatch, last_modified::LastModified,
8};
9
10mod content_type;
11mod etag;
12mod if_modified_since;
13mod if_none_match;
14mod last_modified;
15
16/// A trait for any type which represents an HTTP header.
17pub trait Header: Sized {
18    /// The name of the header.
19    fn header_name() -> http::HeaderName;
20
21    /// Decode the header from a `HeaderValue`.
22    fn decode(value: &http::HeaderValue) -> Option<Self>;
23
24    /// Encode the header into a `HeaderValue`.
25    fn encode(self) -> http::HeaderValue;
26}
27
28/// An extension trait adding convenience methods to use typed headers.
29pub trait HeaderMapExt {
30    /// Tries to get a typed header from the header map.
31    fn typed_get<H: Header>(&self) -> Option<H>;
32
33    /// Inserts a typed header into the header map.
34    fn typed_insert<H: Header>(&mut self, header: H);
35}
36
37impl HeaderMapExt for http::HeaderMap {
38    fn typed_get<H: Header>(&self) -> Option<H> {
39        self.get(H::header_name())
40            .and_then(|value| H::decode(value))
41    }
42
43    fn typed_insert<H: Header>(&mut self, header: H) {
44        self.insert(H::header_name(), header.encode());
45    }
46}