1use http::HeaderValue;
2
3use crate::Error;
4
5pub(crate) use self::entity::{EntityTag, EntityTagRange};
8pub(crate) use self::flat_csv::{FlatCsv, SemiColon};
9pub(crate) use self::fmt::fmt;
10pub(crate) use self::http_date::HttpDate;
11pub(crate) use self::iter::IterExt;
12pub(crate) use self::seconds::Seconds;
15pub(crate) use self::value_string::HeaderValueString;
16
17pub(crate) mod csv;
19mod entity;
21mod flat_csv;
22mod fmt;
23mod http_date;
24mod iter;
25mod seconds;
27mod value_string;
28
29macro_rules! error_type {
30 ($name:ident) => {
31 #[doc(hidden)]
32 pub struct $name {
33 _inner: (),
34 }
35
36 impl ::std::fmt::Debug for $name {
37 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
38 f.debug_struct(stringify!($name)).finish()
39 }
40 }
41
42 impl ::std::fmt::Display for $name {
43 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
44 f.write_str(stringify!($name))
45 }
46 }
47
48 impl ::std::error::Error for $name {}
49 };
50}
51
52macro_rules! derive_header {
53 ($type:ident(_), name: $name:ident) => {
54 impl crate::Header for $type {
55 fn name() -> &'static ::http::header::HeaderName {
56 &::http::header::$name
57 }
58
59 fn decode<'i, I>(values: &mut I) -> Result<Self, crate::Error>
60 where
61 I: Iterator<Item = &'i ::http::header::HeaderValue>,
62 {
63 crate::util::TryFromValues::try_from_values(values).map($type)
64 }
65
66 fn encode<E: Extend<crate::HeaderValue>>(&self, values: &mut E) {
67 values.extend(::std::iter::once((&self.0).into()));
68 }
69 }
70 };
71}
72
73pub(crate) trait TryFromValues: Sized {
75 fn try_from_values<'i, I>(values: &mut I) -> Result<Self, Error>
77 where
78 Self: Sized,
79 I: Iterator<Item = &'i HeaderValue>;
80}
81
82impl TryFromValues for HeaderValue {
83 fn try_from_values<'i, I>(values: &mut I) -> Result<Self, Error>
84 where
85 I: Iterator<Item = &'i HeaderValue>,
86 {
87 values.next().cloned().ok_or_else(Error::invalid)
88 }
89}