sdp_rs/lines/connection/
connection_address.rs1use crate::Error;
2use std::{convert::TryFrom, net::IpAddr};
3
4pub use crate::tokenizers::connection::connection_address::Tokenizer;
7
8#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Copy)]
10pub struct ConnectionAddress {
11 pub base: IpAddr,
12 pub ttl: Option<u32>,
13 pub numaddr: Option<u32>,
14}
15
16impl<'a> TryFrom<Tokenizer<'a>> for ConnectionAddress {
17 type Error = Error;
18
19 fn try_from(tokenizer: Tokenizer<'a>) -> Result<Self, Self::Error> {
20 Ok(Self {
21 base: tokenizer.base.parse().map_err(|e| {
22 Self::Error::parser_with_error("connection address base", tokenizer.base, e)
23 })?,
24 ttl: tokenizer
25 .ttl
26 .map(|ttl| {
27 ttl.parse().map_err(|e| {
28 Self::Error::parser_with_error("connection address ttl", ttl, e)
29 })
30 })
31 .transpose()?,
32 numaddr: tokenizer
33 .numaddr
34 .map(|numaddr| {
35 numaddr.parse().map_err(|e| {
36 Self::Error::parser_with_error("connection number of addresses", numaddr, e)
37 })
38 })
39 .transpose()?,
40 })
41 }
42}
43
44impl<'a> From<IpAddr> for ConnectionAddress {
45 fn from(base: IpAddr) -> Self {
46 Self {
47 base,
48 ttl: None,
49 numaddr: None,
50 }
51 }
52}
53
54impl std::fmt::Display for ConnectionAddress {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 match (self.ttl, self.numaddr) {
57 (Some(ttl), Some(numaddr)) => write!(f, "{}/{}/{}", self.base, ttl, numaddr),
58 (Some(ttl), None) => write!(f, "{}/{}", self.base, ttl),
59 (None, Some(numaddr)) => write!(f, "{}/{}", self.base, numaddr),
60 (None, None) => write!(f, "{}", self.base),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn from_tokenizer1() {
71 let tokenizer: Tokenizer = "233.252.0.1".into();
72
73 assert_eq!(
74 ConnectionAddress::try_from(tokenizer),
75 Ok(ConnectionAddress {
76 base: "233.252.0.1".parse().unwrap(),
77 ttl: None,
78 numaddr: None
79 })
80 );
81 }
82
83 #[test]
84 fn from_tokenizer2() {
85 let tokenizer: Tokenizer = ("233.252.0.1", Some("127"), None).into();
86
87 assert_eq!(
88 ConnectionAddress::try_from(tokenizer),
89 Ok(ConnectionAddress {
90 base: "233.252.0.1".parse().unwrap(),
91 ttl: Some(127),
92 numaddr: None
93 })
94 );
95 }
96
97 #[test]
98 fn from_tokenizer3() {
99 let tokenizer: Tokenizer = ("233.252.0.1", Some("127"), Some("2")).into();
100
101 assert_eq!(
102 ConnectionAddress::try_from(tokenizer),
103 Ok(ConnectionAddress {
104 base: "233.252.0.1".parse().unwrap(),
105 ttl: Some(127),
106 numaddr: Some(2)
107 })
108 );
109 }
110
111 #[test]
112 fn display1() {
113 let connection = ConnectionAddress {
114 base: "233.252.0.1".parse().unwrap(),
115 ttl: Some(127),
116 numaddr: Some(2),
117 };
118
119 assert_eq!(connection.to_string(), "233.252.0.1/127/2");
120 }
121}