ftth_rsip/headers/typed/
contact.rs

1#[doc(hidden)]
2pub use super::tokenizers::DisplayUriParamsTokenizer as Tokenizer;
3
4use crate::common::{
5    uri::{param, Param},
6    Uri,
7};
8use rsip_derives::{TypedHeader, UriAndParamsHelpers};
9use std::convert::{TryFrom, TryInto};
10
11/// The `Contact` header in its [typed](super) form.
12#[derive(TypedHeader, UriAndParamsHelpers, Eq, PartialEq, Clone, Debug)]
13pub struct Contact {
14    pub display_name: Option<String>,
15    pub uri: Uri,
16    pub params: Vec<Param>,
17}
18
19impl Contact {
20    pub fn expires(&self) -> Option<&param::Expires> {
21        self.params.iter().find_map(|param| match param {
22            Param::Expires(expires) => Some(expires),
23            _ => None,
24        })
25    }
26}
27
28impl<'a> TryFrom<Tokenizer<'a>> for Contact {
29    type Error = crate::Error;
30
31    fn try_from(tokenizer: Tokenizer) -> Result<Self, Self::Error> {
32        Ok(Contact {
33            display_name: tokenizer.display_name.map(Into::into),
34            uri: tokenizer.uri.try_into()?,
35            params: tokenizer
36                .params
37                .into_iter()
38                .map(TryInto::try_into)
39                .collect::<Result<Vec<_>, _>>()?,
40        })
41    }
42}
43
44impl std::fmt::Display for Contact {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        match &self.display_name {
47            Some(display_name) => write!(
48                f,
49                "{} <{}>{}",
50                display_name,
51                self.uri,
52                self.params
53                    .iter()
54                    .map(|s| s.to_string())
55                    .collect::<Vec<_>>()
56                    .join("")
57            ),
58            None => write!(
59                f,
60                "<{}>{}",
61                self.uri,
62                self.params
63                    .iter()
64                    .map(|s| s.to_string())
65                    .collect::<Vec<_>>()
66                    .join("")
67            ),
68        }
69    }
70}
71
72impl std::convert::From<crate::common::Uri> for Contact {
73    fn from(uri: crate::common::Uri) -> Self {
74        Self {
75            display_name: None,
76            uri,
77            params: Default::default(),
78        }
79    }
80}