ftth_rsip/headers/typed/
contact.rs1#[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#[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<¶m::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}