1use crate::rr::Class;
2use crate::DomainName;
3use std::convert::TryFrom;
4use std::fmt::{Display, Formatter, Result as FmtResult};
5use std::ops::Deref;
6use thiserror::Error;
7
8struct_domain_name_domain_name!(
9 RP,
13 mbox_dname,
14 txt_dname
15);
16
17try_from_enum_to_integer_without_display! {
18 #[repr(u16)]
19 #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
20 pub enum AFSDBSubtype {
21 VolumeLocationServer = 1,
22 DCEAuthenticationServer = 2,
23 }
24}
25
26impl Display for AFSDBSubtype {
27 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
28 match self {
29 AFSDBSubtype::VolumeLocationServer => write!(f, "1"),
30 AFSDBSubtype::DCEAuthenticationServer => write!(f, "2"),
31 }
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Hash)]
39pub struct AFSDB {
40 pub domain_name: DomainName,
41 pub ttl: u32,
42 pub class: Class,
43 pub subtype: AFSDBSubtype,
44 pub hostname: DomainName,
45}
46
47impl_to_type!(AFSDB);
48
49impl Display for AFSDB {
50 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
51 write!(
52 f,
53 "{} {} {} AFSDB {} {}",
54 self.domain_name, self.ttl, self.class, self.subtype, self.hostname
55 )
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)]
60pub enum PSDNAddressError {
61 #[error("PSDN address contains illegal character: {0}")]
62 IllegalChar(char),
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Hash)]
66pub struct PSDNAddress(String);
67
68impl TryFrom<String> for PSDNAddress {
69 type Error = PSDNAddressError;
70
71 fn try_from(psdn_address: String) -> Result<Self, Self::Error> {
72 for c in psdn_address.chars() {
73 if !c.is_ascii_digit() {
74 return Err(PSDNAddressError::IllegalChar(c));
75 }
76 }
77 Ok(PSDNAddress(psdn_address))
78 }
79}
80
81impl Deref for PSDNAddress {
82 type Target = str;
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88
89impl Display for PSDNAddress {
90 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
91 write!(f, "{}", self.0,)
92 }
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Hash)]
99pub struct X25 {
100 pub domain_name: DomainName,
101 pub ttl: u32,
102 pub class: Class,
103 pub psdn_address: PSDNAddress,
104}
105
106impl_to_type!(X25);
107
108impl Display for X25 {
109 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
110 write!(
111 f,
112 "{} {} {} X25 {}",
113 self.domain_name, self.ttl, self.class, self.psdn_address,
114 )
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)]
119pub enum ISDNError {
120 #[error("Address contains illegal character: {0}")]
121 IllegalChar(char),
122 #[error("SA contains illegal character: {0}")]
123 IllegalCharSA(char),
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Hash)]
127pub struct ISDNAddress(String);
128
129impl TryFrom<String> for ISDNAddress {
130 type Error = ISDNError;
131
132 fn try_from(isdn_address: String) -> Result<Self, Self::Error> {
133 for c in isdn_address.chars() {
134 if !c.is_ascii_digit() {
135 return Err(ISDNError::IllegalChar(c));
136 }
137 }
138 Ok(ISDNAddress(isdn_address))
139 }
140}
141
142impl Deref for ISDNAddress {
143 type Target = str;
144
145 fn deref(&self) -> &Self::Target {
146 &self.0
147 }
148}
149
150impl Display for ISDNAddress {
151 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
152 write!(f, "{}", self.0,)
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Eq, Hash)]
157pub struct SA(String);
158
159impl TryFrom<String> for SA {
160 type Error = ISDNError;
161
162 fn try_from(sa: String) -> Result<Self, Self::Error> {
163 for c in sa.chars() {
164 if !c.is_ascii_hexdigit() {
165 return Err(ISDNError::IllegalCharSA(c));
166 }
167 }
168 Ok(SA(sa))
169 }
170}
171
172impl Deref for SA {
173 type Target = str;
174
175 fn deref(&self) -> &Self::Target {
176 &self.0
177 }
178}
179
180#[derive(Debug, Clone, PartialEq, Eq, Hash)]
184pub struct ISDN {
185 pub domain_name: DomainName,
186 pub ttl: u32,
187 pub class: Class,
188 pub isdn_address: ISDNAddress,
189 pub sa: Option<SA>,
190}
191
192impl_to_type!(ISDN);
193
194impl Display for ISDN {
195 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
196 write!(
197 f,
198 "{} {} {} ISDN {}",
199 self.domain_name, self.ttl, self.class, self.isdn_address,
200 )?;
201 if let Some(sa) = &self.sa {
202 write!(f, " {}", sa.0)?;
203 }
204 Ok(())
205 }
206}
207
208struct_u16_domain_name!(
209 RT,
213 preference,
214 intermediate_host
215);