htmx_types/headers/
mod.rs

1pub mod request;
2pub mod response;
3
4macro_rules! define_header {
5    {
6        $(#[$docs:meta])*
7        ($STATIC:ident, $name_bytes:literal)
8        $($rest:tt)*
9    } => {
10        $(#[$docs])*
11        pub static $STATIC: headers_core::HeaderName = headers_core::HeaderName::from_static($name_bytes);
12
13        $(#[$docs])*
14        #[derive(Debug, Clone, PartialEq, Eq)]
15        $($rest)*
16    };
17}
18use define_header;
19
20macro_rules! true_header {
21    {
22        $(#[$docs:meta])*
23        ($STATIC:ident, $UpCase:ident, $name_bytes:literal)
24    } => {
25        define_header! {
26            $(#[$docs])*
27            ($STATIC, $name_bytes)
28
29            #[derive(Copy)]
30            pub struct $UpCase;
31        }
32
33        impl headers_core::Header for $UpCase {
34            fn name() -> &'static headers_core::HeaderName {
35                &$STATIC
36            }
37
38            fn decode<'i, I>(values: &mut I) -> Result<Self, headers_core::Error>
39            where
40                Self: Sized,
41                I: Iterator<Item = &'i headers_core::HeaderValue>,
42            {
43                match (values.next(), values.next()) {
44                    (Some(value), None) => {
45                        if value == "true" {
46                            Ok(Self)
47                        } else {
48                            Err(headers_core::Error::invalid())
49                        }
50                    }
51                    _ => Err(headers_core::Error::invalid()),
52                }
53            }
54
55            fn encode<E: Extend<headers_core::HeaderValue>>(&self, values: &mut E) {
56                values.extend(std::iter::once(headers_core::HeaderValue::from_static("true")));
57            }
58        }
59    }
60}
61use true_header;
62
63macro_rules! convert_header {
64    {
65        $(#[$docs:meta])*
66        $Ty:ty => ($STATIC:ident, $UpCase:ident, $name_bytes:literal)
67    } => {
68        define_header! {
69            $(#[$docs])*
70            ($STATIC, $name_bytes)
71            pub struct $UpCase(pub $Ty);
72        }
73
74        impl headers_core::Header for $UpCase {
75            fn name() -> &'static headers_core::HeaderName {
76                &$STATIC
77            }
78
79            fn decode<'i, I>(values: &mut I) -> Result<Self, headers_core::Error>
80            where
81                Self: Sized,
82                I: Iterator<Item = &'i headers_core::HeaderValue>,
83            {
84                match (values.next(), values.next()) {
85                    (Some(value), None) => {
86                        value.as_bytes().try_into().map(Self).map_err(|_| headers_core::Error::invalid())
87                    }
88                    _ => Err(headers_core::Error::invalid()),
89                }
90            }
91
92            /// NOTE: Panics if the value cannot be converted to a header value.
93            fn encode<E: Extend<headers_core::HeaderValue>>(&self, values: &mut E) {
94                let s = self.0.to_string();
95                let header = headers_core::HeaderValue::from_str(&s).unwrap();
96                values.extend(std::iter::once(header));
97            }
98        }
99    }
100}
101use convert_header;
102
103macro_rules! string_header {
104    {
105        $(#[$docs:meta])*
106        ($STATIC:ident, $UpCase:ident, $name_bytes:literal)
107    } => {
108        define_header! {
109            $(#[$docs])*
110            ($STATIC, $name_bytes)
111            pub struct $UpCase(pub String);
112        }
113
114        impl headers_core::Header for $UpCase {
115            fn name() -> &'static headers_core::HeaderName {
116                &$STATIC
117            }
118
119            fn decode<'i, I>(values: &mut I) -> Result<Self, headers_core::Error>
120            where
121                Self: Sized,
122                I: Iterator<Item = &'i headers_core::HeaderValue>,
123            {
124                match (values.next(), values.next()) {
125                    (Some(value), None) => {
126                        let s = value.to_str().map_err(|_| headers_core::Error::invalid())?;
127                        Ok(Self(s.to_owned()))
128                    }
129                    _ => Err(headers_core::Error::invalid()),
130                }
131            }
132
133            /// NOTE: Panics if the value cannot be converted to a header value.
134            fn encode<E: Extend<headers_core::HeaderValue>>(&self, values: &mut E) {
135                values.extend(std::iter::once(headers_core::HeaderValue::from_str(&self.0).unwrap()));
136            }
137        }
138    }
139}
140use string_header;