1use crate::headers::untyped::*;
2
3#[doc(hidden)]
4pub use tokenizer::Tokenizer;
5
6#[derive(Debug, PartialEq, Eq, Clone)]
17pub enum Header {
18 Accept(Accept),
19 AcceptEncoding(AcceptEncoding),
20 AcceptLanguage(AcceptLanguage),
21 AlertInfo(AlertInfo),
22 Allow(Allow),
23 AuthenticationInfo(AuthenticationInfo),
24 Authorization(Authorization),
25 CSeq(CSeq),
26 CallId(CallId),
27 CallInfo(CallInfo),
28 Contact(Contact),
29 ContentDisposition(ContentDisposition),
30 ContentEncoding(ContentEncoding),
31 ContentLanguage(ContentLanguage),
32 ContentLength(ContentLength),
33 ContentType(ContentType),
34 Date(Date),
35 ErrorInfo(ErrorInfo),
36 Event(Event),
37 Expires(Expires),
38 From(From),
39 InReplyTo(InReplyTo),
40 MaxForwards(MaxForwards),
41 MimeVersion(MimeVersion),
42 MinExpires(MinExpires),
43 Organization(Organization),
44 Other(String, String),
45 Priority(Priority),
46 ProxyAuthenticate(ProxyAuthenticate),
47 ProxyAuthorization(ProxyAuthorization),
48 ProxyRequire(ProxyRequire),
49 RecordRoute(RecordRoute),
50 ReplyTo(ReplyTo),
51 Require(Require),
52 RetryAfter(RetryAfter),
53 Route(Route),
54 Server(Server),
55 Subject(Subject),
56 SubscriptionState(SubscriptionState),
57 Supported(Supported),
58 Timestamp(Timestamp),
59 To(To),
60 Unsupported(Unsupported),
61 UserAgent(UserAgent),
62 Via(Via),
63 Warning(Warning),
64 WwwAuthenticate(WwwAuthenticate),
65}
66
67impl std::fmt::Display for Header {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 match self {
70 Self::Accept(inner) => write!(f, "{}", inner),
71 Self::AcceptEncoding(inner) => write!(f, "{}", inner),
72 Self::AcceptLanguage(inner) => write!(f, "{}", inner),
73 Self::AlertInfo(inner) => write!(f, "{}", inner),
74 Self::Allow(inner) => write!(f, "{}", inner),
75 Self::AuthenticationInfo(inner) => write!(f, "{}", inner),
76 Self::Authorization(inner) => write!(f, "{}", inner),
77 Self::CSeq(inner) => write!(f, "{}", inner),
78 Self::CallId(inner) => write!(f, "{}", inner),
79 Self::CallInfo(inner) => write!(f, "{}", inner),
80 Self::Contact(inner) => write!(f, "{}", inner),
81 Self::ContentDisposition(inner) => write!(f, "{}", inner),
82 Self::ContentEncoding(inner) => write!(f, "{}", inner),
83 Self::ContentLanguage(inner) => write!(f, "{}", inner),
84 Self::ContentLength(inner) => write!(f, "{}", inner),
85 Self::ContentType(inner) => write!(f, "{}", inner),
86 Self::Date(inner) => write!(f, "{}", inner),
87 Self::ErrorInfo(inner) => write!(f, "{}", inner),
88 Self::Event(inner) => write!(f, "{}", inner),
89 Self::Expires(inner) => write!(f, "{}", inner),
90 Self::From(inner) => write!(f, "{}", inner),
91 Self::InReplyTo(inner) => write!(f, "{}", inner),
92 Self::MaxForwards(inner) => write!(f, "{}", inner),
93 Self::MimeVersion(inner) => write!(f, "{}", inner),
94 Self::MinExpires(inner) => write!(f, "{}", inner),
95 Self::Organization(inner) => write!(f, "{}", inner),
96 Self::Other(key, value) => write!(f, "{}: {}", key, value),
97 Self::Priority(inner) => write!(f, "{}", inner),
98 Self::ProxyAuthenticate(inner) => write!(f, "{}", inner),
99 Self::ProxyAuthorization(inner) => write!(f, "{}", inner),
100 Self::ProxyRequire(inner) => write!(f, "{}", inner),
101 Self::RecordRoute(inner) => write!(f, "{}", inner),
102 Self::ReplyTo(inner) => write!(f, "{}", inner),
103 Self::Require(inner) => write!(f, "{}", inner),
104 Self::RetryAfter(inner) => write!(f, "{}", inner),
105 Self::Route(inner) => write!(f, "{}", inner),
106 Self::Server(inner) => write!(f, "{}", inner),
107 Self::Subject(inner) => write!(f, "{}", inner),
108 Self::SubscriptionState(inner) => write!(f, "{}", inner),
109 Self::Supported(inner) => write!(f, "{}", inner),
110 Self::Timestamp(inner) => write!(f, "{}", inner),
111 Self::To(inner) => write!(f, "{}", inner),
112 Self::Unsupported(inner) => write!(f, "{}", inner),
113 Self::UserAgent(inner) => write!(f, "{}", inner),
114 Self::Via(inner) => write!(f, "{}", inner),
115 Self::Warning(inner) => write!(f, "{}", inner),
116 Self::WwwAuthenticate(inner) => write!(f, "{}", inner),
117 }
118 }
119}
120
121#[doc(hidden)]
122pub mod tokenizer {
123 use super::*;
124 use crate::{Error, IResult, TokenizerError};
125 use rsip_derives::Utf8Tokenizer;
126 use std::convert::TryInto;
127
128 impl<'a> TryInto<Header> for Tokenizer<'a> {
129 type Error = Error;
130
131 fn try_into(self) -> Result<Header, Error> {
132 let tokenizer: Utf8Tokenizer = self.try_into()?;
133
134 match tokenizer.name {
135 s if s.eq_ignore_ascii_case("Accept") => {
136 Ok(Header::Accept(Accept::new(tokenizer.value)))
137 }
138 s if s.eq_ignore_ascii_case("Accept-Encoding") => {
139 Ok(Header::AcceptEncoding(AcceptEncoding::new(tokenizer.value)))
140 }
141 s if s.eq_ignore_ascii_case("Accept-Language") => {
142 Ok(Header::AcceptLanguage(AcceptLanguage::new(tokenizer.value)))
143 }
144 s if s.eq_ignore_ascii_case("Alert-Info") => {
145 Ok(Header::AlertInfo(AlertInfo::new(tokenizer.value)))
146 }
147 s if s.eq_ignore_ascii_case("Allow") => {
148 Ok(Header::Allow(Allow::new(tokenizer.value)))
149 }
150 s if s.eq_ignore_ascii_case("Authentication-Info") => Ok(
151 Header::AuthenticationInfo(AuthenticationInfo::new(tokenizer.value)),
152 ),
153 s if s.eq_ignore_ascii_case("Authorization") => {
154 Ok(Header::Authorization(Authorization::new(tokenizer.value)))
155 }
156 s if s.eq_ignore_ascii_case("CSeq") => Ok(Header::CSeq(CSeq::new(tokenizer.value))),
157 s if s.eq_ignore_ascii_case("Call-Id") || s.eq_ignore_ascii_case("i") => {
158 Ok(Header::CallId(CallId::new(tokenizer.value)))
159 }
160 s if s.eq_ignore_ascii_case("Call-Info") => {
161 Ok(Header::CallInfo(CallInfo::new(tokenizer.value)))
162 }
163 s if s.eq_ignore_ascii_case("Contact") || s.eq_ignore_ascii_case("m") => {
164 Ok(Header::Contact(Contact::new(tokenizer.value)))
165 }
166 s if s.eq_ignore_ascii_case("Content-Disposition") => Ok(
167 Header::ContentDisposition(ContentDisposition::new(tokenizer.value)),
168 ),
169 s if s.eq_ignore_ascii_case("Content-Encoding") || s.eq_ignore_ascii_case("e") => Ok(Header::ContentEncoding(
170 ContentEncoding::new(tokenizer.value),
171 )),
172 s if s.eq_ignore_ascii_case("Content-Language") => Ok(Header::ContentLanguage(
173 ContentLanguage::new(tokenizer.value),
174 )),
175 s if s.eq_ignore_ascii_case("Content-Length") || s.eq_ignore_ascii_case("l") => {
176 Ok(Header::ContentLength(ContentLength::new(tokenizer.value)))
177 }
178 s if s.eq_ignore_ascii_case("Content-Type") || s.eq_ignore_ascii_case("c") => {
179 Ok(Header::ContentType(ContentType::new(tokenizer.value)))
180 }
181 s if s.eq_ignore_ascii_case("Date") => Ok(Header::Date(Date::new(tokenizer.value))),
182 s if s.eq_ignore_ascii_case("Error-Info") => {
183 Ok(Header::ErrorInfo(ErrorInfo::new(tokenizer.value)))
184 }
185 s if s.eq_ignore_ascii_case("Event") => {
186 Ok(Header::Event(Event::new(tokenizer.value)))
187 }
188 s if s.eq_ignore_ascii_case("Expires") => {
189 Ok(Header::Expires(Expires::new(tokenizer.value)))
190 }
191 s if s.eq_ignore_ascii_case("From") || s.eq_ignore_ascii_case("f") => Ok(Header::From(From::new(tokenizer.value))),
192 s if s.eq_ignore_ascii_case("In-Reply-To") => {
193 Ok(Header::InReplyTo(InReplyTo::new(tokenizer.value)))
194 }
195 s if s.eq_ignore_ascii_case("Max-Forwards") => {
196 Ok(Header::MaxForwards(MaxForwards::new(tokenizer.value)))
197 }
198 s if s.eq_ignore_ascii_case("Mime-Version") => {
199 Ok(Header::MimeVersion(MimeVersion::new(tokenizer.value)))
200 }
201 s if s.eq_ignore_ascii_case("Min-Expires") => {
202 Ok(Header::MinExpires(MinExpires::new(tokenizer.value)))
203 }
204 s if s.eq_ignore_ascii_case("Organization") => {
205 Ok(Header::Organization(Organization::new(tokenizer.value)))
206 }
207 s if s.eq_ignore_ascii_case("Priority") => {
208 Ok(Header::Priority(Priority::new(tokenizer.value)))
209 }
210 s if s.eq_ignore_ascii_case("Proxy-Authenticate") => Ok(Header::ProxyAuthenticate(
211 ProxyAuthenticate::new(tokenizer.value),
212 )),
213 s if s.eq_ignore_ascii_case("Proxy-Authorization") => Ok(
214 Header::ProxyAuthorization(ProxyAuthorization::new(tokenizer.value)),
215 ),
216 s if s.eq_ignore_ascii_case("Proxy-Require") => {
217 Ok(Header::ProxyRequire(ProxyRequire::new(tokenizer.value)))
218 }
219 s if s.eq_ignore_ascii_case("Record-Route") => {
220 Ok(Header::RecordRoute(RecordRoute::new(tokenizer.value)))
221 }
222 s if s.eq_ignore_ascii_case("Reply-To") => {
223 Ok(Header::ReplyTo(ReplyTo::new(tokenizer.value)))
224 }
225 s if s.eq_ignore_ascii_case("Require") => {
226 Ok(Header::Require(Require::new(tokenizer.value)))
227 }
228 s if s.eq_ignore_ascii_case("Retry-After") => {
229 Ok(Header::RetryAfter(RetryAfter::new(tokenizer.value)))
230 }
231 s if s.eq_ignore_ascii_case("Route") => {
232 Ok(Header::Route(Route::new(tokenizer.value)))
233 }
234 s if s.eq_ignore_ascii_case("Server") => {
235 Ok(Header::Server(Server::new(tokenizer.value)))
236 }
237 s if s.eq_ignore_ascii_case("Subject") || s.eq_ignore_ascii_case("s") => {
238 Ok(Header::Subject(Subject::new(tokenizer.value)))
239 }
240 s if s.eq_ignore_ascii_case("Supported") || s.eq_ignore_ascii_case("k") => {
241 Ok(Header::Supported(Supported::new(tokenizer.value)))
242 }
243 s if s.eq_ignore_ascii_case("Timestamp") => {
244 Ok(Header::Timestamp(Timestamp::new(tokenizer.value)))
245 }
246 s if s.eq_ignore_ascii_case("To") || s.eq_ignore_ascii_case("t") => Ok(Header::To(To::new(tokenizer.value))),
247 s if s.eq_ignore_ascii_case("Unsupported") => {
248 Ok(Header::Unsupported(Unsupported::new(tokenizer.value)))
249 }
250 s if s.eq_ignore_ascii_case("User-Agent") => {
251 Ok(Header::UserAgent(UserAgent::new(tokenizer.value)))
252 }
253 s if s.eq_ignore_ascii_case("Via") || s.eq_ignore_ascii_case("v") => Ok(Header::Via(Via::new(tokenizer.value))),
254 s if s.eq_ignore_ascii_case("Warning") => {
255 Ok(Header::Warning(Warning::new(tokenizer.value)))
256 }
257 s if s.eq_ignore_ascii_case("WWW-Authenticate") => Ok(Header::WwwAuthenticate(
258 WwwAuthenticate::new(tokenizer.value),
259 )),
260 _ => Ok(Header::Other(tokenizer.name.into(), tokenizer.value.into())),
261 }
262 }
263 }
264
265 #[derive(Debug, PartialEq, Eq, Utf8Tokenizer)]
266 pub struct Tokenizer<'a> {
267 pub name: &'a [u8],
268 pub value: &'a [u8],
269 }
270
271 impl<'a> Tokenizer<'a> {
272 pub fn tokenize(part: &'a [u8]) -> IResult<Self> {
273 use crate::NomError;
274 use nom::{
275 branch::alt,
276 bytes::complete::{tag, take_until, take_while1},
277 character::complete::space0,
278 combinator::{map, rest},
279 sequence::tuple,
280 };
281
282 let (rem, (name, _, _, value)) = tuple((
283 take_while1(crate::parser_utils::is_token),
284 tag(":"),
285 space0,
286 alt((
287 map(tuple((take_until("\r\n"), tag("\r\n"))), |(value, _)| value),
288 rest,
289 )),
290 ))(part)
291 .map_err(|_: NomError<'a>| TokenizerError::from(("header", part)).into())?;
292
293 Ok((rem, (name, value).into()))
294 }
295 }
296
297 impl<'a> std::convert::From<(&'a [u8], &'a [u8])> for Tokenizer<'a> {
298 fn from(tuple: (&'a [u8], &'a [u8])) -> Self {
299 Self {
300 name: tuple.0,
301 value: tuple.1,
302 }
303 }
304 }
305}