dns_message_parser/rr/edns/
rfc_7871.rs1use crate::rr::{Address, AddressError};
2use std::cmp::max;
3use std::fmt::{Display, Formatter, Result as FmtResult};
4
5#[derive(Debug, PartialEq, Clone, Eq, Hash)]
6pub struct ECS {
7 source_prefix_length: u8,
8 scope_prefix_length: u8,
9 address: Address,
10}
11
12macro_rules! setter {
13 ($(#[$doc_comment:meta])* $method:ident, $member:ident, $type:ident) => {
14 $(#[$doc_comment])*
15 pub fn $method(&mut self, new_value: $type) -> Result<(), AddressError> {
16 let previous = self.$member.clone();
17 self.$member = new_value;
18 match self.check_addr() {
19 Ok(()) => Ok(()),
20 Err(address_error) => {
21 self.$member = previous;
22 Err(address_error)
23 }
24 }
25 }
26 };
27}
28
29impl ECS {
30 fn check_addr(&self) -> Result<(), AddressError> {
31 let prefix_length = self.get_prefix_length();
32 self.address.check_prefix(prefix_length)
33 }
34
35 pub fn new(
36 source_prefix_length: u8,
37 scope_prefix_length: u8,
38 address: Address,
39 ) -> Result<ECS, AddressError> {
40 let ecs = ECS {
41 source_prefix_length,
42 scope_prefix_length,
43 address,
44 };
45
46 ecs.check_addr()?;
47
48 Ok(ecs)
49 }
50
51 #[inline]
53 pub const fn get_source_prefix_length(&self) -> u8 {
54 self.source_prefix_length
55 }
56
57 setter!(
58 set_source_prefix_length,
65 source_prefix_length,
66 u8
67 );
68
69 #[inline]
71 pub const fn get_scope_prefix_length(&self) -> u8 {
72 self.scope_prefix_length
73 }
74
75 setter!(
76 set_scope_prefix_length,
83 scope_prefix_length,
84 u8
85 );
86
87 #[inline]
89 pub const fn get_address(&self) -> &Address {
90 &self.address
91 }
92
93 setter!(
94 set_address,
101 address,
102 Address
103 );
104
105 #[inline]
109 pub fn get_prefix_length(&self) -> u8 {
110 max(self.source_prefix_length, self.scope_prefix_length)
111 }
112}
113
114impl Display for ECS {
115 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
116 write!(
117 f,
118 "ECS {} {} {}",
119 self.source_prefix_length, self.scope_prefix_length, self.address
120 )
121 }
122}