rama_http_headers/
header.rs

1use rama_http_types::{HeaderName, HeaderValue};
2
3use std::error;
4use std::fmt::{self, Display, Formatter};
5
6/// A trait for any object that will represent a header field and value.
7///
8/// This trait represents the construction and identification of headers,
9/// and contains trait-object unsafe methods.
10pub trait Header {
11    /// The name of this header.
12    fn name() -> &'static HeaderName;
13
14    /// Decode this type from an iterator of [`HeaderValue`]s.
15    fn decode<'i, I>(values: &mut I) -> Result<Self, Error>
16    where
17        Self: Sized,
18        I: Iterator<Item = &'i HeaderValue>;
19
20    /// Encode this type to a [`HeaderValue`], and add it to a container
21    /// which has [`HeaderValue`] type as each element.
22    ///
23    /// This function should be infallible. Any errors converting to a
24    /// `HeaderValue` should have been caught when parsing or constructing
25    /// this value.
26    fn encode<E: Extend<HeaderValue>>(&self, values: &mut E);
27
28    /// Encode this [`Header`] to [`HeaderValue`].
29    fn encode_to_value(&self) -> HeaderValue {
30        let mut container = ExtendOnce(None);
31        self.encode(&mut container);
32        container.0.unwrap()
33    }
34}
35
36struct ExtendOnce(Option<HeaderValue>);
37
38impl Extend<HeaderValue> for ExtendOnce {
39    fn extend<T: IntoIterator<Item = HeaderValue>>(&mut self, iter: T) {
40        self.0 = iter.into_iter().next();
41    }
42}
43
44/// Errors trying to decode a header.
45#[derive(Debug)]
46pub struct Error {
47    kind: Kind,
48}
49
50#[derive(Debug)]
51enum Kind {
52    Invalid,
53}
54
55impl Error {
56    /// Create an 'invalid' Error.
57    pub fn invalid() -> Error {
58        Error {
59            kind: Kind::Invalid,
60        }
61    }
62}
63
64impl Display for Error {
65    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
66        match &self.kind {
67            Kind::Invalid => f.write_str("invalid HTTP header"),
68        }
69    }
70}
71
72impl error::Error for Error {}