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