From: Richard Whitehouse Date: Sun, 21 Oct 2018 22:32:07 +0000 (-0400) Subject: Format using cargo fmt X-Git-Url: https://git.richardwhiuk.com/?a=commitdiff_plain;h=357887e8cc246b5a1c17016687be36898db4850e;p=rust-sip.git Format using cargo fmt --- diff --git a/src/codec.rs b/src/codec.rs index abfc36a..91120d5 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -2,17 +2,17 @@ use bytes::BytesMut; use futures::future; use futures::{Future, Stream}; -use tokio_core::reactor::Handle; -use tokio_core::net::TcpListener; -use tokio_io::codec::{Encoder, Decoder}; -use std::io; -use std; use nom; +use std; +use std::io; use std::sync::Arc; +use tokio_core::net::TcpListener; +use tokio_core::reactor::Handle; +use tokio_io::codec::{Decoder, Encoder}; -use types::{RequestLine, StatusLine, TopLine, Header}; -use parser::top_line; use parser::header; +use parser::top_line; +use types::{Header, RequestLine, StatusLine, TopLine}; const SPACE: u8 = b' '; const TAB: u8 = b'\t'; @@ -31,7 +31,6 @@ impl Header { } } - #[derive(Clone, Debug)] struct UnparsedLine { value: BytesMut, @@ -82,7 +81,6 @@ impl SipCodec { trace!("Gathering CRLF"); if let Some(cr) = search.position(|&b| b == CR) { - trace!("Found CR at {}", cr); total += cr; @@ -105,18 +103,22 @@ impl SipCodec { trace!("Using line: {:?}", std::str::from_utf8(&line)); - match (&mut self.top_line, chartype(line.first()), &mut self.latest_header) { + match ( + &mut self.top_line, + chartype(line.first()), + &mut self.latest_header, + ) { // Ignore empty top lines (&mut None, CharType::Line, _) => { - trace!("Ignoring empty top line"); - } // Top line beginnning with whitespace - ignore (&mut None, CharType::Whitespace, _) => { - trace!("Got top line beginning with whitespace - ignore: {:?}", - line); + trace!( + "Got top line beginning with whitespace - ignore: {:?}", + line + ); } // Top line with no headers! Discard. @@ -159,10 +161,9 @@ impl SipCodec { trace!("Got end of headers"); - if let Ok(new_message) = PartialMessage::new(top_line.take() - .unwrap(), - &mut self.headers) { - + if let Ok(new_message) = + PartialMessage::new(top_line.take().unwrap(), &mut self.headers) + { debug!("Got partial message: {:?}", new_message); self.headers.clear(); @@ -200,7 +201,6 @@ impl SipCodec { } } } - } } @@ -211,12 +211,16 @@ struct PartialMessage { } impl PartialMessage { - fn new(top_line: UnparsedLine, - headers: &mut Vec) - -> Result { + fn new( + top_line: UnparsedLine, + headers: &mut Vec, + ) -> Result { Ok(PartialMessage { top_line: top_line, - headers: headers.drain(..).filter_map(|line| Header::parse(line)).collect(), + headers: headers + .drain(..) + .filter_map(|line| Header::parse(line)) + .collect(), }) } @@ -266,20 +270,16 @@ impl Message { fn parse(message: PartialMessage, body: Option) -> Option { match top_line(message.top_line.as_bytes()) { - nom::IResult::Done(_, TopLine::RequestLine(r)) => { - Some(Message::Request(Request { - headers: message.headers, - request_line: (r, message.top_line.clone()), - body: body, - })) - } - nom::IResult::Done(_, TopLine::StatusLine(s)) => { - Some(Message::Response(Response { - headers: message.headers, - status_line: (s, message.top_line.clone()), - body: body, - })) - } + nom::IResult::Done(_, TopLine::RequestLine(r)) => Some(Message::Request(Request { + headers: message.headers, + request_line: (r, message.top_line.clone()), + body: body, + })), + nom::IResult::Done(_, TopLine::StatusLine(s)) => Some(Message::Response(Response { + headers: message.headers, + status_line: (s, message.top_line.clone()), + body: body, + })), result => { warn!("Failed to parse top line: {:?}", result); None @@ -305,15 +305,15 @@ impl Decoder for SipCodec { fn decode(&mut self, buf: &mut BytesMut) -> io::Result> { if let Some(_) = self.message { - trace!("Gathering body"); let length = self.message.iter().map(|m| m.body_length()).next().unwrap(); if length > buf.len() { return Ok(None); - } else if let Some(message) = Message::new_with_body(self.message.take().unwrap(), - buf.split_to(length)) { + } else if let Some(message) = + Message::new_with_body(self.message.take().unwrap(), buf.split_to(length)) + { return Ok(Some(message)); } else { warn!("Failed to parse message with no body!"); @@ -354,47 +354,50 @@ fn chartype(char: Option<&u8>) -> CharType { impl Sip { pub fn new() -> Sip { - Sip { listeners: Vec::new() } + Sip { + listeners: Vec::new(), + } } pub fn add_listener(&mut self, listener: TcpListener) { self.listeners.push(listener); } - pub fn run(self, - handle: Handle, - caller: Arc>) - -> Box> - where F: 'static + Fn(Message) -> Result<(), std::io::Error> + pub fn run( + self, + handle: Handle, + caller: Arc>, + ) -> Box> + where + F: 'static + Fn(Message) -> Result<(), std::io::Error>, { - let mut future: Box> = Box::new(future::ok(())); for listener in self.listeners { - let handle = handle.clone(); let caller = caller.clone(); // Iterate incoming connections - future = Box::new(future.join(listener.incoming().for_each(move |(tcp, _)| { - - let caller = caller.clone(); + future = Box::new( + future + .join(listener.incoming().for_each(move |(tcp, _)| { + let caller = caller.clone(); - // Split up the read and write halves - let decoder = SipCodec::new(); + // Split up the read and write halves + let decoder = SipCodec::new(); - let (_sink, stream) = decoder.framed(tcp).split(); + let (_sink, stream) = decoder.framed(tcp).split(); - let future = stream.for_each(move |message| caller(message)); + let future = stream.for_each(move |message| caller(message)); - let future = future.map_err(|err| error!("Error {:?}", err)); + let future = future.map_err(|err| error!("Error {:?}", err)); - // Spawn the future as a concurrent task - handle.spawn(future); + // Spawn the future as a concurrent task + handle.spawn(future); - Ok(()) - })) - .map(|_| ())); + Ok(()) + })).map(|_| ()), + ); } future @@ -406,19 +409,19 @@ mod tests { extern crate env_logger; - use std::ops::DerefMut; - use std::sync::Arc; - use std::sync::Mutex; - use codec::Sip; use codec::Message; + use codec::Sip; use futures; - use futures::Future; use futures::future::Either; - use tokio_io::io; + use futures::Future; + use std::net::Shutdown; + use std::ops::DerefMut; + use std::sync::Arc; + use std::sync::Mutex; use tokio_core::net::TcpListener; use tokio_core::net::TcpStream; use tokio_core::reactor::Core; - use std::net::Shutdown; + use tokio_io::io; use types::Method; fn decode_sip_message>(message: S) -> Message { @@ -437,12 +440,14 @@ mod tests { let server = { let m = m.clone(); - sip.run(core.handle(), - Arc::new(Box::new(move |message| { - let mut m = m.lock().unwrap(); - *m = Some(message); - Ok(()) - }))) + sip.run( + core.handle(), + Arc::new(Box::new(move |message| { + let mut m = m.lock().unwrap(); + *m = Some(message); + Ok(()) + })), + ) }; // Send a request @@ -466,8 +471,10 @@ mod tests { // Response match (res, message.deref_mut()) { - (Ok(Either::B(((ref _socket, ref _response), _))), - ref mut message @ &mut Some(_)) => message.take().unwrap(), + ( + Ok(Either::B(((ref _socket, ref _response), _))), + ref mut message @ &mut Some(_), + ) => message.take().unwrap(), (Err(Either::A((err, _))), _) => panic!("{:?}", err), (Err(Either::B((err, _))), _) => panic!("{:?}", err), (_, &mut None) => panic!("No message received"), @@ -480,53 +487,54 @@ mod tests { fn test_message_decode() { env_logger::init().unwrap(); - let message = - decode_sip_message("MESSAGE sip:test.com SIP/2.0\r\n\ - Accept: text/plain\r\n\ - Accept-Encoding: *\r\n\ - Accept-Language: en-gb\r\n\ - Alert-Info: \r\n\ - Allow: MESSAGE\r\n\ - Authentication-Info: qop=auth\r\n\ - Authorization: Digest username=\"Alice\"\r\n\ - Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com\r\n\ - Call-Info: ; purpose=icon\r\n\ - Contact: *\r\n\ - Content-Disposition: session\r\n\ - Content-Encoding: gzip\r\n\ - Content-Language: en-gb\r\n\ - Content-Length: 0\r\n\ - Content-Type: text/plain\r\n\ - CSeq: 1 MESSAGE\r\n\ - Date: Sat, 13 Nov 2010 23:29:00 GMT\r\n\ - Error-Info: \r\n\ - Expires: 30\r\n\ - From: sip:+12125551212@server.phone2net.com; tag=887s\r\n\ - In-Reply-To: 70710@saturn.bell-tel.com,17320@saturn.bell-tel. com\r\n\ - Max-Forwards: 32\r\n\ - MIME-Version:2.0\r\n\ - Min-Expires: 30\r\n\ - Organization: Foobar\r\n\ - Priority: normal\r\n\ - Proxy-Authenticate: Digest realm=\"atlanta.com\"\r\n\ - Proxy-Authorization: Digest username=\"Bob\"\r\n\ - Proxy-Require: foo\r\n\ - Record-Route: \r\n\ - Reply-To: \r\n\ - Require: baz\r\n\ - Retry-After:18000;duration=3600\r\n\ - Route: \r\n\ - Server: rust-sip tokio\r\n\ - Subject: Foobaz\r\n\ - Supported: rec\r\n\ - Timestamp: 1 2\r\n\ - To: ; tag=287447\r\n\ - Unsupported: 100rel\r\n\ - User-Agent: rust-sip\r\n\ - Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds\r\n\ - Warning: 370 devnull \"Failure\"\r\n\ - WWW-Authenticate: Digest realm=\"biloxi.com\"\r\n\ - X-Extension: test\r\n\r\n"); + let message = decode_sip_message( + "MESSAGE sip:test.com SIP/2.0\r\n\ + Accept: text/plain\r\n\ + Accept-Encoding: *\r\n\ + Accept-Language: en-gb\r\n\ + Alert-Info: \r\n\ + Allow: MESSAGE\r\n\ + Authentication-Info: qop=auth\r\n\ + Authorization: Digest username=\"Alice\"\r\n\ + Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com\r\n\ + Call-Info: ; purpose=icon\r\n\ + Contact: *\r\n\ + Content-Disposition: session\r\n\ + Content-Encoding: gzip\r\n\ + Content-Language: en-gb\r\n\ + Content-Length: 0\r\n\ + Content-Type: text/plain\r\n\ + CSeq: 1 MESSAGE\r\n\ + Date: Sat, 13 Nov 2010 23:29:00 GMT\r\n\ + Error-Info: \r\n\ + Expires: 30\r\n\ + From: sip:+12125551212@server.phone2net.com; tag=887s\r\n\ + In-Reply-To: 70710@saturn.bell-tel.com,17320@saturn.bell-tel. com\r\n\ + Max-Forwards: 32\r\n\ + MIME-Version:2.0\r\n\ + Min-Expires: 30\r\n\ + Organization: Foobar\r\n\ + Priority: normal\r\n\ + Proxy-Authenticate: Digest realm=\"atlanta.com\"\r\n\ + Proxy-Authorization: Digest username=\"Bob\"\r\n\ + Proxy-Require: foo\r\n\ + Record-Route: \r\n\ + Reply-To: \r\n\ + Require: baz\r\n\ + Retry-After:18000;duration=3600\r\n\ + Route: \r\n\ + Server: rust-sip tokio\r\n\ + Subject: Foobaz\r\n\ + Supported: rec\r\n\ + Timestamp: 1 2\r\n\ + To: ; tag=287447\r\n\ + Unsupported: 100rel\r\n\ + User-Agent: rust-sip\r\n\ + Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds\r\n\ + Warning: 370 devnull \"Failure\"\r\n\ + WWW-Authenticate: Digest realm=\"biloxi.com\"\r\n\ + X-Extension: test\r\n\r\n", + ); if let Message::Request(request) = message { assert_eq!(request.request_line.0.method, Method::MESSAGE); diff --git a/src/lib.rs b/src/lib.rs index 9993435..bc3d893 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ -#![recursion_limit="128"] +#![recursion_limit = "128"] +extern crate bytes; extern crate futures; extern crate tokio_core; extern crate tokio_io; -extern crate bytes; #[macro_use] extern crate log; @@ -11,6 +11,6 @@ extern crate log; #[macro_use] extern crate nom; -mod types; -mod parser; pub mod codec; +mod parser; +mod types; diff --git a/src/parser/header.rs b/src/parser/header.rs index c954219..b04975c 100644 --- a/src/parser/header.rs +++ b/src/parser/header.rs @@ -4,7 +4,9 @@ use parser::*; // Accept Header -named!(media_main_type, alt!( +named!( + media_main_type, + alt!( // Discrete Types tag!(b"text") => { |_| MediaMainType::Text } | tag!(b"image") => { |_| MediaMainType::Image } | @@ -15,202 +17,222 @@ named!(media_main_type, alt!( tag!(b"message") => { |_| MediaMainType::Message } | tag!(b"multipart") => { |_| MediaMainType::Multipart } | // Extensions - token => { |x| MediaMainType::Extension(x) })); + token => { |x| MediaMainType::Extension(x) }) +); // We don't bother splitting IANA, IETF and x- token types. use self::token as media_subtype; use self::token as media_attribute; -named!(media_value>, alt!( - token | - quoted_string)); +named!(media_value>, alt!(token | quoted_string)); -named!(media_parameter, separated_pair!( - media_attribute, - tag!(b"="), - media_value)); +named!( + media_parameter, + separated_pair!(media_attribute, tag!(b"="), media_value) +); -named!(media_type, separated_pair!( - media_main_type, - tag!(b"/"), - media_subtype)); +named!( + media_type, + separated_pair!(media_main_type, tag!(b"/"), media_subtype) +); -named!(media_range, tuple!( - alt!( +named!( + media_range, + tuple!( + alt!( tag!(b"*/*") => { |_| MediaFullType::All } | terminated!(media_main_type, tag!(b"/*")) => { |x| MediaFullType::Partial(x) } | /**/ media_type => { |(t, st)| MediaFullType::Specific(t, st) }), - many0!( - preceded!(tag!(b";"), media_parameter)))); + many0!(preceded!(tag!(b";"), media_parameter)) + ) +); -named!(generic_param, separated_pair!( - token, - tag!(b"="), - opt!(token))); +named!( + generic_param, + separated_pair!(token, tag!(b"="), opt!(token)) +); use self::float as qvalue; named!(qparam, preceded!(tag!(b"q="), qvalue)); -named!(accept_param, alt!( +named!( + accept_param, + alt!( qparam => { |x| AcceptParam::Qvalue(x) } | - generic_param => { |x| AcceptParam::Generic(x) })); - -named!(accept_range, tuple!( - media_range, - many0!(preceded!( - tag!(b";"), - accept_param)))); - -named!(accept_header>, preceded!( - terminated!(tag!(b"Accept"), hcolon), - separated_nonempty_list!( - tag!(b","), - accept_range))); - -named!(codings, alt!( + generic_param => { |x| AcceptParam::Generic(x) }) +); + +named!( + accept_range, + tuple!(media_range, many0!(preceded!(tag!(b";"), accept_param))) +); + +named!( + accept_header>, + preceded!( + terminated!(tag!(b"Accept"), hcolon), + separated_nonempty_list!(tag!(b","), accept_range) + ) +); + +named!( + codings, + alt!( tag!(b"*") => { |_| Coding::All } | token => { |t| Coding::Content(t) } -)); - -named!(encoding, tuple!( - codings, - many0!(preceded!( - tag!(b";"), - accept_param)))); - -named!(accept_encoding_header>, preceded!( - terminated!(tag!(b"Accept-Encoding"), hcolon), - separated_nonempty_list!( - tag!(b","), - encoding))); +) +); + +named!( + encoding, + tuple!(codings, many0!(preceded!(tag!(b";"), accept_param))) +); + +named!( + accept_encoding_header>, + preceded!( + terminated!(tag!(b"Accept-Encoding"), hcolon), + separated_nonempty_list!(tag!(b","), encoding) + ) +); named!(language_token>, many1!(alpha)); -named!(language_tag, separated_nonempty_list!( - tag!(b"-"), - language_token)); +named!( + language_tag, + separated_nonempty_list!(tag!(b"-"), language_token) +); -named!(language_range, alt!( +named!( + language_range, + alt!( tag!(b"*") => { |_| LanguageRange::All } | - language_tag => { |x : LanguageTag| LanguageRange::Range(x) })); - -named!(language, tuple!( - language_range, - many0!(preceded!( - tag!(b";"), - accept_param)))); - -named!(accept_language_header>, preceded!( - terminated!(tag!(b"Accept-Language"), hcolon), - separated_nonempty_list!( - tag!(b","), - language))); - -named!(alert_param, tuple!( - delimited!( - tag!(b"<"), - absolute_uri, - tag!(b">") - ), - many0!(generic_param))); - -named!(alert_info_header>, preceded!( - terminated!(tag!(b"Alert-Info"), hcolon), - separated_nonempty_list!( - tag!(b","), - alert_param))); - -named!(allow_header>, preceded!( - terminated!(tag!(b"Allow"), hcolon), - separated_nonempty_list!( - tag!(b","), - method))); - -named!(nextnonce>, preceded!( - tag!(b"nc="), - quoted_string)); - -named!(qop_value, alt!( + language_tag => { |x : LanguageTag| LanguageRange::Range(x) }) +); + +named!( + language, + tuple!(language_range, many0!(preceded!(tag!(b";"), accept_param))) +); + +named!( + accept_language_header>, + preceded!( + terminated!(tag!(b"Accept-Language"), hcolon), + separated_nonempty_list!(tag!(b","), language) + ) +); + +named!( + alert_param, + tuple!( + delimited!(tag!(b"<"), absolute_uri, tag!(b">")), + many0!(generic_param) + ) +); + +named!( + alert_info_header>, + preceded!( + terminated!(tag!(b"Alert-Info"), hcolon), + separated_nonempty_list!(tag!(b","), alert_param) + ) +); + +named!( + allow_header>, + preceded!( + terminated!(tag!(b"Allow"), hcolon), + separated_nonempty_list!(tag!(b","), method) + ) +); + +named!(nextnonce>, preceded!(tag!(b"nc="), quoted_string)); + +named!( + qop_value, + alt!( tag!(b"auth") => { |x| Qop::Auth } | tag!(b"auth-init") => { |x| Qop::AuthInit } | - token => { |x| Qop::Token(x) })); + token => { |x| Qop::Token(x) }) +); -named!(message_qop, preceded!( - tag!(b"qop="), - qop_value)); +named!(message_qop, preceded!(tag!(b"qop="), qop_value)); -named!(response_digest>, delimited!( - tag!(b"\""), - many0!(hex), - tag!(b"\""))); +named!( + response_digest>, + delimited!(tag!(b"\""), many0!(hex), tag!(b"\"")) +); -named!(response_auth>, preceded!( - tag!(b"rspauth="), - response_digest)); +named!( + response_auth>, + preceded!(tag!(b"rspauth="), response_digest) +); -named!(cnonce>, preceded!( - tag!(b"cnonce="), - quoted_string)); +named!(cnonce>, preceded!(tag!(b"cnonce="), quoted_string)); named!(nc_value>, many1!(lhex)); -named!(nonce_count>, preceded!( - tag!(b"nc="), - nc_value)); +named!(nonce_count>, preceded!(tag!(b"nc="), nc_value)); -named!(ainfo, alt!( +named!( + ainfo, + alt!( nextnonce => { |n| AuthenticationInfo::NextNonce(n) } | message_qop => { |m| AuthenticationInfo::MessageQop(m) } | response_auth => { |r| AuthenticationInfo::ResponseAuth(r) } | cnonce => { |c| AuthenticationInfo::Cnonce(c) } | - nonce_count => { |n| AuthenticationInfo::NonceCount(n) })); - -named!(authentication_info_header>, preceded!( - terminated!(tag!(b"Authentication-Info"), hcolon), - separated_nonempty_list!( - tag!(b","), - ainfo))); - -named!(username>, preceded!( - tag!(b"username="), - quoted_string)); - -named!(realm>, preceded!( - tag!(b"realm="), - quoted_string)); - -named!(nonce>, preceded!( - tag!(b"nonce="), - quoted_string)); - -named!(digest_uri>, preceded!( - tag!(b"digest_uri="), - quoted_string)); - -named!(dresponse>, preceded!( - tag!(b"response="), - response_digest)); - -named!(algorithm, alt!( + nonce_count => { |n| AuthenticationInfo::NonceCount(n) }) +); + +named!( + authentication_info_header>, + preceded!( + terminated!(tag!(b"Authentication-Info"), hcolon), + separated_nonempty_list!(tag!(b","), ainfo) + ) +); + +named!( + username>, + preceded!(tag!(b"username="), quoted_string) +); + +named!(realm>, preceded!(tag!(b"realm="), quoted_string)); + +named!(nonce>, preceded!(tag!(b"nonce="), quoted_string)); + +named!( + digest_uri>, + preceded!(tag!(b"digest_uri="), quoted_string) +); + +named!( + dresponse>, + preceded!(tag!(b"response="), response_digest) +); + +named!( + algorithm, + alt!( tag!("MD5") => { |_| Algorithm::Md5 } | tag!("MD5-sess") => { |_| Algorithm::Md5Session } | token => { |t| Algorithm::Token(t) } -)); +) +); -named!(opaque>, preceded!( - tag!(b"opaque="), - quoted_string)); +named!(opaque>, preceded!(tag!(b"opaque="), quoted_string)); -named!(auth_param, separated_pair!( - token, - tag!(b"="), - alt!( - token | - quoted_string))); +named!( + auth_param, + separated_pair!(token, tag!(b"="), alt!(token | quoted_string)) +); -named!(digest_response>, many1!(alt!( +named!( + digest_response>, + many1!(alt!( username => { |u| DigestResponse::Username(u) } | realm => { |r| DigestResponse::Realm(r) } | nonce => { |n| DigestResponse::Nonce(n) } | @@ -221,167 +243,211 @@ named!(digest_response>, many1!(alt!( opaque => { |o| DigestResponse::Opaque(o) } | message_qop => { |m| DigestResponse::MessageQop(m) } | nonce_count => { |n| DigestResponse::NonceCount(n) } | - auth_param => { |(k, v)| DigestResponse::AuthParam(k, v) }))); - -named!(other_response<(Vec, Vec)>, separated_pair!( - token, - tag!(b" "), - separated_nonempty_list!( - tag!(b","), - auth_param))); - -named!(credentials, alt!( + auth_param => { |(k, v)| DigestResponse::AuthParam(k, v) })) +); + +named!( + other_response<(Vec, Vec)>, + separated_pair!( + token, + tag!(b" "), + separated_nonempty_list!(tag!(b","), auth_param) + ) +); + +named!( + credentials, + alt!( preceded!( tag!(b"Digest "), digest_response) => { |d| Credentials::Digest(d) } | - other_response => { |(s,p)| Credentials::Other(s, p) })); - -named!(authorization_header, preceded!( - terminated!(tag!(b"Authorization"), hcolon), - credentials)); - -named!(call_id, tuple!( - word, - opt!(preceded!( - tag!(b"@"), - word)))); - -named!(call_id_header, preceded!( - terminated!(alt!(tag!(b"Call-ID") | tag!(b"i")), hcolon), - call_id)); - -named!(purpose, alt!( + other_response => { |(s,p)| Credentials::Other(s, p) }) +); + +named!( + authorization_header, + preceded!(terminated!(tag!(b"Authorization"), hcolon), credentials) +); + +named!( + call_id, + tuple!(word, opt!(preceded!(tag!(b"@"), word))) +); + +named!( + call_id_header, + preceded!( + terminated!(alt!(tag!(b"Call-ID") | tag!(b"i")), hcolon), + call_id + ) +); + +named!( + purpose, + alt!( tag!(b"icon") => { |_| Purpose::Icon } | tag!(b"info") => { |_| Purpose::Info } | tag!(b"card") => { |_| Purpose::Card } | - token => { |t| Purpose::Token(t) })); + token => { |t| Purpose::Token(t) }) +); -named!(info_param, alt!( +named!( + info_param, + alt!( preceded!( tag!(b"purpose="), purpose) => { |p| InfoParam::Purpose(p) } | - generic_param => { |g| InfoParam::Generic(g) })); - -named!(info, tuple!( - delimited!( - tag!(b"<"), - absolute_uri, - tag!(b">") - ), - many0!(preceded!( - tag!(b";"), - info_param)))); - -named!(call_info_header>, preceded!( - terminated!(tag!(b"Call-Info"), hcolon), - separated_nonempty_list!( - tag!(","), - info))); - -named!(display_name>, alt!( - token | - quoted_string)); - -named!(name_addr, tuple!( - opt!(display_name), - delimited!( - tag!(b"<"), - uri, - tag!(b">")))); - -named!(expires, preceded!( - tag!(b"expires="), - number)); - -named!(contact_param, alt!( + generic_param => { |g| InfoParam::Generic(g) }) +); + +named!( + info, + tuple!( + delimited!(tag!(b"<"), absolute_uri, tag!(b">")), + many0!(preceded!(tag!(b";"), info_param)) + ) +); + +named!( + call_info_header>, + preceded!( + terminated!(tag!(b"Call-Info"), hcolon), + separated_nonempty_list!(tag!(","), info) + ) +); + +named!(display_name>, alt!(token | quoted_string)); + +named!( + name_addr, + tuple!(opt!(display_name), delimited!(tag!(b"<"), uri, tag!(b">"))) +); + +named!(expires, preceded!(tag!(b"expires="), number)); + +named!( + contact_param, + alt!( qparam => {|q| ContactParam::Qvalue(q) } | expires => {|e| ContactParam::Expires(e) } | - generic_param => {|g| ContactParam::Generic(g) })); + generic_param => {|g| ContactParam::Generic(g) }) +); -named!(target, - alt!( +named!( + target, + alt!( name_addr => { |(n, u)| Target::Name(n, u) } | // With this target variant, parameters conflict - so they aren't allowed // See RFC 3261 Section 20.10 - uri_np => { |u| Target::Uri(u) })); - -named!(contact_target<(Target, Vec)>, tuple!( - target, - many0!(preceded!( - tag!(b";"), - contact_param - )))); - -named!(contact_header, preceded!( - terminated!(alt!(tag!(b"Contact") | tag!(b"m")), hcolon), - alt!( + uri_np => { |u| Target::Uri(u) }) +); + +named!( + contact_target<(Target, Vec)>, + tuple!(target, many0!(preceded!(tag!(b";"), contact_param))) +); + +named!( + contact_header, + preceded!( + terminated!(alt!(tag!(b"Contact") | tag!(b"m")), hcolon), + alt!( tag!(b"*") => { |_| Contact::Star } | separated_nonempty_list!( tag!(","), - contact_target) => { |c| Contact::Contact(c) }))); + contact_target) => { |c| Contact::Contact(c) }) + ) +); -named!(disp_type, alt!( +named!( + disp_type, + alt!( tag!(b"render") => { |_| DispositionType::Render } | tag!(b"session") => { |_| DispositionType::Session } | tag!(b"icon") => { |_| DispositionType::Icon } | tag!(b"alert") => { |_| DispositionType::Alert } | token => { |t| DispositionType::Token(t) } -)); +) +); -named!(handling, alt!( +named!( + handling, + alt!( tag!(b"optional") => { |_| Handling::Optional } | tag!(b"required") => { |_| Handling::Required } | - token => { |t| Handling::Token(t) })); + token => { |t| Handling::Token(t) }) +); -named!(disp_param, alt!( +named!( + disp_param, + alt!( preceded!(tag!(b"handling="), handling) => { |h| DispositionParam::Handling(h) } | - generic_param => { |g| DispositionParam::Generic(g) })); - -named!(content_disposition_header<(DispositionType, Vec)>, preceded!( - terminated!(tag!(b"Content-Disposition"), hcolon), - tuple!( - disp_type, - many0!(preceded!( - tag!(b";"), - disp_param))))); - -named!(content_encoding_header>, preceded!( - terminated!(alt!(tag!(b"Content-Encoding") | tag!(b"e")), hcolon), - separated_nonempty_list!( - tag!(b","), - token))); - -named!(content_language_header>, preceded!( - terminated!(tag!(b"Content-Language"), hcolon), - separated_nonempty_list!( - tag!(b","), - language_tag))); - -named!(content_length_header, preceded!( - terminated!(alt!(tag!(b"Content-Length") | tag!(b"l")), hcolon), - number)); - -named!(content_type_header, preceded!( - terminated!(alt!(tag!(b"Content-Type") | tag!(b"c")), hcolon), - media_type)); - -named!(cseq_header<(u32, Method)>, preceded!( - terminated!(tag!(b"CSeq"), hcolon), - separated_pair!( - number, - tag!(" "), - method))); - -named!(wkday, alt!( + generic_param => { |g| DispositionParam::Generic(g) }) +); + +named!( + content_disposition_header<(DispositionType, Vec)>, + preceded!( + terminated!(tag!(b"Content-Disposition"), hcolon), + tuple!(disp_type, many0!(preceded!(tag!(b";"), disp_param))) + ) +); + +named!( + content_encoding_header>, + preceded!( + terminated!(alt!(tag!(b"Content-Encoding") | tag!(b"e")), hcolon), + separated_nonempty_list!(tag!(b","), token) + ) +); + +named!( + content_language_header>, + preceded!( + terminated!(tag!(b"Content-Language"), hcolon), + separated_nonempty_list!(tag!(b","), language_tag) + ) +); + +named!( + content_length_header, + preceded!( + terminated!(alt!(tag!(b"Content-Length") | tag!(b"l")), hcolon), + number + ) +); + +named!( + content_type_header, + preceded!( + terminated!(alt!(tag!(b"Content-Type") | tag!(b"c")), hcolon), + media_type + ) +); + +named!( + cseq_header<(u32, Method)>, + preceded!( + terminated!(tag!(b"CSeq"), hcolon), + separated_pair!(number, tag!(" "), method) + ) +); + +named!( + wkday, + alt!( tag!(b"Mon") => { |_| Day::Monday } | tag!(b"Tue") => { |_| Day::Tuesday } | tag!(b"Wed") => { |_| Day::Wednesday } | tag!(b"Thu") => { |_| Day::Thursday } | tag!(b"Fri") => { |_| Day::Friday } | tag!(b"Sat") => { |_| Day::Saturday } | - tag!(b"Sun") => { |_| Day::Sunday })); + tag!(b"Sun") => { |_| Day::Sunday }) +); -named!(month, alt!( +named!( + month, + alt!( tag!(b"Jan") => { |_| Month::January } | tag!(b"Feb") => { |_| Month::February } | tag!(b"Mar") => { |_| Month::March } | @@ -393,318 +459,421 @@ named!(month, alt!( tag!(b"Sep") => { |_| Month::September } | tag!(b"Oct") => { |_| Month::October } | tag!(b"Nov") => { |_| Month::November } | - tag!(b"Dec") => { |_| Month::December })); - -named!(date, tuple!( - terminated!(number, tag!(b" ")), - terminated!(month, tag!(b" ")), - number)); - -named!(time