simple_dns/dns/rdata/
caa.rs1use crate::dns::{CharacterString, WireFormat};
2
3use super::RR;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
9pub struct CAA<'a> {
10 pub flag: u8,
12 pub tag: CharacterString<'a>,
14 pub value: CharacterString<'a>,
16}
17
18impl<'a> RR for CAA<'a> {
19 const TYPE_CODE: u16 = 257;
20}
21
22impl<'a> CAA<'a> {
23 pub fn into_owned<'b>(self) -> CAA<'b> {
25 CAA {
26 flag: self.flag,
27 tag: self.tag.into_owned(),
28 value: self.value.into_owned(),
29 }
30 }
31}
32
33impl<'a> WireFormat<'a> for CAA<'a> {
34 fn parse(data: &'a [u8], position: &mut usize) -> crate::Result<Self>
35 where
36 Self: Sized,
37 {
38 let flag = u8::from_be_bytes(data[*position..*position + 1].try_into()?);
39 *position += 1;
40 let tag = CharacterString::parse(data, position)?;
41 let value = CharacterString::parse(data, position)?;
42
43 Ok(Self { flag, tag, value })
44 }
45
46 fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
47 out.write_all(&self.flag.to_be_bytes())?;
48 self.tag.write_to(out)?;
49 self.value.write_to(out)
50 }
51
52 fn len(&self) -> usize {
53 self.tag.len() + self.value.len() + 1
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn parse_and_write_caa() {
63 let caa = CAA {
64 flag: 0,
65 tag: CharacterString::new(b"issue").unwrap(),
66 value: CharacterString::new(b"\"example.org").unwrap(),
67 };
68
69 let mut data = Vec::new();
70 assert!(caa.write_to(&mut data).is_ok());
71
72 let caa = CAA::parse(&data, &mut 0);
73 assert!(caa.is_ok());
74 let caa = caa.unwrap();
75
76 assert_eq!(data.len(), caa.len());
77 assert_eq!(0, caa.flag);
78 assert_eq!("issue", caa.tag.to_string());
79 assert_eq!("\"example.org", caa.value.to_string());
80 }
81}