dns_message_parser/rr/
rfc_3123.rs

1use crate::rr::{Address, AddressError};
2use crate::DomainName;
3use std::fmt::{Display, Formatter, Result as FmtResult};
4
5pub const APL_NEGATION_MASK: u8 = 0b1000_0000;
6
7#[derive(Debug, PartialEq, Clone, Eq, Hash)]
8pub struct APItem {
9    prefix: u8,
10    pub negation: bool,
11    address: Address,
12}
13
14impl APItem {
15    pub fn new(prefix: u8, negation: bool, address: Address) -> Result<APItem, AddressError> {
16        address.check_prefix(prefix)?;
17
18        let apitem = APItem {
19            prefix,
20            negation,
21            address,
22        };
23
24        Ok(apitem)
25    }
26
27    #[inline]
28    pub const fn get_prefix(&self) -> u8 {
29        self.prefix
30    }
31
32    pub fn set_prefix(&mut self, prefix: u8) -> Result<(), AddressError> {
33        self.address.check_prefix(prefix)?;
34        self.prefix = prefix;
35        Ok(())
36    }
37
38    #[inline]
39    pub const fn get_address(&self) -> &Address {
40        &self.address
41    }
42
43    pub fn set_address(&mut self, address: Address) -> Result<(), AddressError> {
44        address.check_prefix(self.prefix)?;
45        self.address = address;
46        Ok(())
47    }
48}
49
50#[test]
51fn set_prefix() {
52    let address = Address::Ipv6("1122:3344::".parse().unwrap());
53    let mut apitem = APItem::new(64, true, address).unwrap();
54    apitem.set_prefix(96).unwrap();
55}
56
57#[test]
58fn set_address() {
59    let address = Address::Ipv6("1122:3344::".parse().unwrap());
60    let mut apitem = APItem::new(64, true, address).unwrap();
61    let address = Address::Ipv6("1122:3344:55::".parse().unwrap());
62    apitem.set_address(address).unwrap();
63}
64
65impl Display for APItem {
66    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
67        if self.negation {
68            write!(f, "!")?;
69        }
70        write!(
71            f,
72            "{}:{}/{}",
73            self.address.get_address_family_number() as u8,
74            self.address,
75            self.prefix
76        )
77    }
78}
79
80#[derive(Debug, PartialEq, Clone, Eq, Hash)]
81pub struct APL {
82    pub domain_name: DomainName,
83    pub ttl: u32,
84    pub apitems: Vec<APItem>,
85}
86
87impl_to_type!(APL);
88
89impl Display for APL {
90    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
91        write!(f, "{} {} IN APL", self.domain_name, self.ttl,)?;
92        for apitem in &self.apitems {
93            write!(f, " {}", apitem)?;
94        }
95        Ok(())
96    }
97}