dns_message_parser/rr/
rfc_1183.rs

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    /// The [responsible person] resource record type.
10    ///
11    /// [responsible person]: https://tools.ietf.org/html/rfc1183#section-2
12    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/// The [AFS Data base location] resource record type:
36///
37/// [AFS Data base location]: https://tools.ietf.org/html/rfc1183#section-1
38#[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/// The [X25] resource record type.
96///
97/// [X25]: https://tools.ietf.org/html/rfc1183#section-3.1
98#[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/// The [ISDN] resource record type.
181///
182/// [ISDN]: https://tools.ietf.org/html/rfc1183#section-3.2
183#[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    /// The [route through] resource record type.
210    ///
211    /// [route through]: https://tools.ietf.org/html/rfc1183#section-3.3
212    RT,
213    preference,
214    intermediate_host
215);