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