ftth_rsip/headers/typed/
via.rs1#[doc(hidden)]
2pub use super::tokenizers::ViaTokenizer as Tokenizer;
3
4use crate::{
5 common::{
6 uri::{self, param::Branch, Param, Uri},
7 Transport, Version,
8 },
9 Error,
10};
11use rsip_derives::{TypedHeader, UriAndParamsHelpers};
12use std::{
13 convert::{TryFrom, TryInto},
14 net::IpAddr,
15};
16
17#[derive(TypedHeader, UriAndParamsHelpers, Eq, PartialEq, Clone, Debug)]
19pub struct Via {
20 pub version: Version,
21 pub transport: Transport,
22 pub uri: Uri,
24 pub params: Vec<uri::Param>,
25}
26
27impl Via {
28 pub fn branch(&self) -> Result<&Branch, Error> {
29 self.params
30 .iter()
31 .find_map(|param| match param {
32 Param::Branch(branch) => Some(branch),
33 _ => None,
34 })
35 .ok_or_else(|| Error::missing_param("branch"))
36 }
37
38 pub fn received(&self) -> Result<Option<IpAddr>, std::net::AddrParseError> {
39 self.params
40 .iter()
41 .find_map(|param| match param {
42 Param::Received(received) => Some(received.parse()),
43 _ => None,
44 })
45 .transpose()
46 }
47
48 pub fn sent_by(&self) -> &Uri {
49 &self.uri
50 }
51
52 pub fn sent_protocol(&self) -> &Transport {
53 &self.transport
54 }
55}
56
57impl<'a> TryFrom<Tokenizer<'a>> for Via {
58 type Error = crate::Error;
59
60 fn try_from(tokenizer: Tokenizer) -> Result<Self, Self::Error> {
61 Ok(Via {
62 version: tokenizer.version.try_into()?,
63 transport: tokenizer.transport.try_into()?,
64 uri: tokenizer.uri.try_into()?,
65 params: tokenizer
66 .params
67 .into_iter()
68 .map(TryInto::try_into)
69 .collect::<Result<Vec<_>, _>>()?,
70 })
71 }
72}
73
74impl std::fmt::Display for Via {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(
77 f,
78 "{}/{} {}{}",
79 self.version,
80 self.transport,
81 self.uri,
82 self.params
83 .iter()
84 .map(|s| s.to_string())
85 .collect::<Vec<_>>()
86 .join("")
87 )
88 }
89}
90
91impl std::convert::From<crate::common::Uri> for Via {
92 fn from(uri: crate::common::Uri) -> Self {
93 Self {
94 version: Default::default(),
95 transport: Default::default(),
96 uri,
97 params: vec![Param::Branch(Default::default())],
98 }
99 }
100}