1use std::cmp::Ordering;
2use std::str::FromStr;
3
4use http::header::{HeaderName, InvalidHeaderName};
5
6#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum PseudoHeader {
14 RequestTarget,
21 Created,
23 Expires,
25}
26
27impl PseudoHeader {
28 pub fn as_str(&self) -> &str {
30 match self {
31 PseudoHeader::RequestTarget => "(request-target)",
32 PseudoHeader::Created => "(created)",
33 PseudoHeader::Expires => "(expires)",
34 }
35 }
36}
37
38impl FromStr for PseudoHeader {
39 type Err = ();
40 fn from_str(s: &str) -> Result<PseudoHeader, Self::Err> {
41 match s {
42 "(request-target)" => Ok(PseudoHeader::RequestTarget),
43 "(created)" => Ok(PseudoHeader::Created),
44 "(expires)" => Ok(PseudoHeader::Expires),
45 _ => Err(()),
46 }
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
55pub enum Header {
56 Pseudo(PseudoHeader),
58 Normal(HeaderName),
60}
61
62impl Header {
63 pub fn as_str(&self) -> &str {
66 match self {
67 Header::Pseudo(h) => h.as_str(),
68 Header::Normal(h) => h.as_str(),
69 }
70 }
71}
72
73impl FromStr for Header {
74 type Err = InvalidHeaderName;
75 fn from_str(s: &str) -> Result<Header, Self::Err> {
76 PseudoHeader::from_str(s)
77 .map(Into::into)
78 .or_else(|_| HeaderName::from_str(s).map(Into::into))
79 }
80}
81
82impl Ord for Header {
83 fn cmp(&self, other: &Header) -> Ordering {
84 self.as_str().cmp(other.as_str())
85 }
86}
87
88impl PartialOrd for Header {
89 fn partial_cmp(&self, other: &Header) -> Option<Ordering> {
90 Some(self.cmp(other))
91 }
92}
93
94impl From<HeaderName> for Header {
95 fn from(other: HeaderName) -> Self {
96 Header::Normal(other)
97 }
98}
99
100impl From<PseudoHeader> for Header {
101 fn from(other: PseudoHeader) -> Self {
102 Header::Pseudo(other)
103 }
104}