sipmsg/headers/parsers/
retry_after.rs1use crate::{
2 common::{
3 bnfcore::is_digit, errorparse::SipParseError, nom_wrappers::take_sws, take_sws_token,
4 },
5 headers::{
6 header::{HeaderTagType, HeaderTags, HeaderValue, HeaderValueType},
7 traits::SipHeaderParser,
8 },
9};
10use nom::bytes::complete::{take_until, take_while1};
11
12pub struct RetryAfter;
13
14impl SipHeaderParser for RetryAfter {
15 fn take_value(source_input: &[u8]) -> nom::IResult<&[u8], HeaderValue, SipParseError> {
16 let (input, seconds) = take_while1(is_digit)(source_input)?;
17 let (input, _) = take_sws(input)?;
18 let mut tags = HeaderTags::new();
19 tags.insert(HeaderTagType::Seconds, seconds);
20 if !input.is_empty() && input[0] == b'(' {
21 let (input, _) = take_sws_token::lparen(input)?;
22 let (input, comment) = take_until(")")(input)?;
23 let input = &input[1..]; tags.insert(HeaderTagType::Comment, comment);
25 let (_, hdr_val) = HeaderValue::new(
26 &source_input[..source_input.len() - input.len()],
27 HeaderValueType::RetryAfter,
28 Some(tags),
29 None,
30 )?;
31 return Ok((input, hdr_val));
32 }
33 let (_, hdr_val) = HeaderValue::new(
34 &source_input[..source_input.len() - input.len()],
35 HeaderValueType::RetryAfter,
36 Some(tags),
37 None,
38 )?;
39 return Ok((input, hdr_val));
40 }
41}
42
43#[cfg(test)]
44mod test {
45 use super::*;
46
47 #[test]
48 fn test_retryafter_value() {
49 let (input, val) = RetryAfter::take_value("120 (I'm in a meeting)\r\n".as_bytes()).unwrap();
50 assert_eq!(val.vstr, "120 (I'm in a meeting)");
51 assert_eq!(
52 val.tags().unwrap()[&HeaderTagType::Comment],
53 "I'm in a meeting".as_bytes()
54 );
55 assert_eq!(
56 val.tags().unwrap()[&HeaderTagType::Seconds],
57 "120".as_bytes()
58 );
59 assert_eq!(input, b"\r\n");
60 }
61}