rsip/headers/typed/tokenizers/
display_uri_params.rs

1use crate::{common::uri, headers::typed::Tokenize, Error};
2
3#[derive(Eq, PartialEq, Clone, Debug)]
4pub struct DisplayUriParamsTokenizer<'a> {
5    pub display_name: Option<&'a str>,
6    pub uri: uri::Tokenizer<'a, &'a str, char>,
7    pub params: Vec<uri::param::Tokenizer<'a, &'a str, char>>,
8}
9
10impl<'a> Tokenize<'a> for DisplayUriParamsTokenizer<'a> {
11    fn tokenize(part: &'a str) -> Result<Self, Error> {
12        use crate::parser_utils::is_empty_or_fail_with;
13        use nom::{
14            bytes::complete::{tag, take_until},
15            combinator::rest,
16            error::VerboseError,
17            multi::many0,
18            sequence::tuple,
19        };
20
21        if part.contains('<') {
22            let (_, (display_name, _, uri, _, params)) = tuple::<_, _, VerboseError<&str>, _>((
23                take_until("<"),
24                tag("<"),
25                take_until(">"),
26                tag(">"),
27                rest,
28            ))(part)
29            .map_err(|_| Error::tokenizer(("header parts", part)))?;
30
31            let (rem, params) = many0(uri::param::Tokenizer::tokenize)(params)
32                .map_err(|_| Error::tokenizer(("params", part)))?;
33            is_empty_or_fail_with(rem, ("params tokenizing left trailing input", part))?;
34
35            Ok(Self {
36                display_name: crate::utils::opt_trim(display_name),
37                uri: uri::Tokenizer::tokenize(uri)
38                    .map_err(|_| Error::tokenizer(("URI in addr-spec", part)))?
39                    .1,
40                params,
41            })
42        } else {
43            let (_, (uri, params)) = tuple((
44                uri::Tokenizer::tokenize_without_params,
45                many0(uri::param::Tokenizer::tokenize),
46            ))(part)?;
47
48            Ok(Self {
49                display_name: None,
50                uri,
51                params,
52            })
53        }
54    }
55}