1mod addr_record;
4mod naptr_record;
5mod srv_record;
6
7pub use addr_record::AddrRecord;
8pub use naptr_record::{NaptrEntry, NaptrFlags, NaptrRecord, NaptrServices};
9pub use srv_record::{SrvEntry, SrvRecord};
10
11use rsip::{Domain, Error, Transport};
12use std::convert::TryFrom;
13
14#[derive(Debug, Clone, Hash, Eq, PartialEq)]
17pub struct SrvDomain {
18 pub domain: Domain,
19 pub protocol: Transport,
20 pub secure: bool,
21}
22
23impl SrvDomain {
24 pub fn transport(&self) -> Transport {
25 match (self.secure, self.protocol) {
26 (true, Transport::Tcp) => Transport::Tls,
27 (true, Transport::Sctp) => Transport::TlsSctp,
28 (true, Transport::Ws) => Transport::Wss,
29 _ => self.protocol,
30 }
31 }
32}
33
34impl TryFrom<NaptrEntry> for SrvDomain {
40 type Error = rsip::Error;
41
42 fn try_from(entry: NaptrEntry) -> Result<Self, Self::Error> {
43 match SrvDomain::try_from(entry.replacement.clone()) {
44 Ok(srv_domain) => Ok(srv_domain),
45 Err(_) => Err(Error::Unexpected(format!(
46 "Can't convert into SrvDomain for Naptr Entry with replacement {}",
47 entry.replacement
48 ))),
49 }
50 }
51}
52
53impl From<(Domain, Transport)> for SrvDomain {
54 fn from(tuple: (Domain, Transport)) -> Self {
55 Self { domain: tuple.0, protocol: tuple.1.protocol(), secure: false }
56 }
57}
58
59impl std::fmt::Display for SrvDomain {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 match self.secure {
62 true => {
63 write!(f, "_sips._{}.{}", self.protocol.to_string().to_lowercase(), self.domain)
64 }
65 false => {
66 write!(f, "_sip._{}.{}", self.protocol.to_string().to_lowercase(), self.domain)
67 }
68 }
69 }
70}
71
72impl TryFrom<Domain> for SrvDomain {
73 type Error = rsip::Error;
74
75 fn try_from(from: Domain) -> Result<Self, Self::Error> {
76 Self::try_from(from.to_string().as_str())
77 }
78}
79
80impl TryFrom<&str> for SrvDomain {
81 type Error = rsip::Error;
82
83 fn try_from(from: &str) -> Result<Self, Self::Error> {
84 use nom::{
85 bytes::complete::{tag, take_until},
86 error::VerboseError,
87 sequence::tuple,
88 };
89 use std::convert::TryInto;
90
91 let (rem, (_, scheme, _)) =
92 tuple::<_, _, VerboseError<&str>, _>((tag("_"), take_until("."), tag(".")))(from)
93 .map_err(|_| Error::tokenizer(("SrvDomain scheme", from)))?;
94 let scheme: rsip::Scheme =
95 rsip::common::uri::scheme::Tokenizer::from(scheme.as_bytes()).try_into()?;
96
97 let (domain, (_, transport, _)) =
98 tuple::<_, _, VerboseError<&str>, _>((tag("_"), take_until("."), tag(".")))(rem)
99 .map_err(|_| Error::tokenizer(("SrvDomain transport", from)))?;
100 let transport: rsip::Transport =
101 rsip::common::transport::Tokenizer::from(transport.as_bytes()).try_into()?;
102
103 Ok(Self {
104 secure: scheme.is_sips()?,
105 protocol: transport.protocol(),
106 domain: domain.into(),
107 })
108 }
109}