simple_dns/dns/rdata/
naptr.rs1use crate::dns::{CharacterString, Name, WireFormat};
2
3use super::RR;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
10pub struct NAPTR<'a> {
11 pub order: u16,
13 pub preference: u16,
15 pub flags: CharacterString<'a>,
17 pub services: CharacterString<'a>,
19 pub regexp: CharacterString<'a>,
21 pub replacement: Name<'a>,
23}
24
25impl<'a> RR for NAPTR<'a> {
26 const TYPE_CODE: u16 = 35;
27}
28
29impl<'a> NAPTR<'a> {
30 pub fn into_owned<'b>(self) -> NAPTR<'b> {
32 NAPTR {
33 order: self.order,
34 preference: self.preference,
35 flags: self.flags.into_owned(),
36 services: self.services.into_owned(),
37 regexp: self.regexp.into_owned(),
38 replacement: self.replacement.into_owned(),
39 }
40 }
41}
42
43impl<'a> WireFormat<'a> for NAPTR<'a> {
44 fn parse(data: &'a [u8], position: &mut usize) -> crate::Result<Self>
45 where
46 Self: Sized,
47 {
48 let order = u16::from_be_bytes(data[*position..*position + 2].try_into()?);
49 *position += 2;
50 let preference = u16::from_be_bytes(data[*position..*position + 2].try_into()?);
51 *position += 2;
52 let flags = CharacterString::parse(data, position)?;
53 let services = CharacterString::parse(data, position)?;
54 let regexp = CharacterString::parse(data, position)?;
55 let replacement = Name::parse(data, position)?;
56
57 Ok(Self {
58 order,
59 preference,
60 flags,
61 services,
62 regexp,
63 replacement,
64 })
65 }
66
67 fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
68 out.write_all(&self.order.to_be_bytes())?;
69 out.write_all(&self.preference.to_be_bytes())?;
70 self.flags.write_to(out)?;
71 self.services.write_to(out)?;
72 self.regexp.write_to(out)?;
73 self.replacement.write_to(out)
74 }
75
76 fn len(&self) -> usize {
77 self.flags.len() + self.services.len() + self.regexp.len() + self.replacement.len() + 4
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn parse_and_write_naptr() {
87 let naptr = NAPTR {
88 order: 0,
89 preference: 1,
90 flags: CharacterString::new(b"123abc").unwrap(),
91 services: CharacterString::new(b"test").unwrap(),
92 regexp: CharacterString::new(b"@\\w+\\.\\w{2,3}(\\.\\w{2,3})?").unwrap(),
93 replacement: Name::new("e.exchange.com").unwrap(),
94 };
95
96 let mut data = Vec::new();
97 assert!(naptr.write_to(&mut data).is_ok());
98
99 let naptr = NAPTR::parse(&data, &mut 0);
100 assert!(naptr.is_ok());
101 let naptr = naptr.unwrap();
102
103 assert_eq!(data.len(), naptr.len());
104 assert_eq!(0, naptr.order);
105 assert_eq!(1, naptr.preference);
106 assert_eq!("123abc", naptr.flags.to_string());
107 assert_eq!("test", naptr.services.to_string());
108 assert_eq!("@\\w+\\.\\w{2,3}(\\.\\w{2,3})?", naptr.regexp.to_string());
109 assert_eq!("e.exchange.com", naptr.replacement.to_string());
110 }
111}