rsip/headers/typed/tokenizers/
display_uri_params.rs1use 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}