sipmsg/headers/parsers/
retry_after.rs

1use 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..]; // skio )
24            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}