1#[cfg(not(feature = "std"))]
27use core::net::AddrParseError;
28use core::{fmt, ops::Deref, str};
29#[cfg(feature = "std")]
30use std::net::AddrParseError;
31
32#[cfg(not(feature = "std"))]
33pub use core::net::Ipv6Addr;
34#[cfg(feature = "std")]
35pub use std::net::Ipv6Addr;
36
37#[cfg(feature = "serde")]
38use serde::{Deserialize, Serialize};
39
40use crate::{
41 error::ProtoResult,
42 rr::{RData, RecordData, RecordType},
43 serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder},
44};
45
46#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
48#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
49pub struct AAAA(pub Ipv6Addr);
50
51impl AAAA {
52 #[allow(clippy::too_many_arguments)]
54 pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Self {
55 Self(Ipv6Addr::new(a, b, c, d, e, f, g, h))
56 }
57}
58
59impl RecordData for AAAA {
60 fn try_from_rdata(data: RData) -> Result<Self, crate::rr::RData> {
61 match data {
62 RData::AAAA(ipv4) => Ok(ipv4),
63 _ => Err(data),
64 }
65 }
66
67 fn try_borrow(data: &RData) -> Option<&Self> {
68 match data {
69 RData::AAAA(ipv6) => Some(ipv6),
70 _ => None,
71 }
72 }
73
74 fn record_type(&self) -> RecordType {
75 RecordType::AAAA
76 }
77
78 fn into_rdata(self) -> RData {
79 RData::AAAA(self)
80 }
81}
82
83impl BinEncodable for AAAA {
84 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
85 let segments = self.segments();
86
87 encoder.emit_u16(segments[0])?;
89 encoder.emit_u16(segments[1])?;
90 encoder.emit_u16(segments[2])?;
91 encoder.emit_u16(segments[3])?;
92 encoder.emit_u16(segments[4])?;
93 encoder.emit_u16(segments[5])?;
94 encoder.emit_u16(segments[6])?;
95 encoder.emit_u16(segments[7])?;
96 Ok(())
97 }
98}
99
100impl<'r> BinDecodable<'r> for AAAA {
101 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
102 let a: u16 = decoder.read_u16()?.unverified();
104 let b: u16 = decoder.read_u16()?.unverified();
105 let c: u16 = decoder.read_u16()?.unverified();
106 let d: u16 = decoder.read_u16()?.unverified();
107 let e: u16 = decoder.read_u16()?.unverified();
108 let f: u16 = decoder.read_u16()?.unverified();
109 let g: u16 = decoder.read_u16()?.unverified();
110 let h: u16 = decoder.read_u16()?.unverified();
111
112 Ok(Ipv6Addr::new(a, b, c, d, e, f, g, h).into())
113 }
114}
115
116#[allow(clippy::many_single_char_names)]
118#[deprecated(note = "use the BinDecodable::read method instead")]
119pub fn read(decoder: &mut BinDecoder<'_>) -> ProtoResult<AAAA> {
120 <AAAA as BinDecodable>::read(decoder)
121}
122
123#[deprecated(note = "use the BinEncodable::emit method instead")]
125pub fn emit(encoder: &mut BinEncoder<'_>, address: &Ipv6Addr) -> ProtoResult<()> {
126 BinEncodable::emit(&AAAA::from(*address), encoder)
127}
128
129impl From<Ipv6Addr> for AAAA {
130 fn from(aaaa: Ipv6Addr) -> Self {
131 Self(aaaa)
132 }
133}
134
135impl From<AAAA> for Ipv6Addr {
136 fn from(aaaa: AAAA) -> Self {
137 aaaa.0
138 }
139}
140
141impl Deref for AAAA {
142 type Target = Ipv6Addr;
143
144 fn deref(&self) -> &Self::Target {
145 &self.0
146 }
147}
148
149impl fmt::Display for AAAA {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
151 write!(f, "{}", self.0)
152 }
153}
154
155impl str::FromStr for AAAA {
156 type Err = AddrParseError;
157 fn from_str(s: &str) -> Result<Self, AddrParseError> {
158 Ipv6Addr::from_str(s).map(From::from)
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use alloc::vec::Vec;
165 use core::str::FromStr;
166
167 use super::*;
168 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
169
170 fn get_data() -> Vec<(AAAA, Vec<u8>)> {
171 vec![
172 (
173 AAAA::from_str("::").unwrap(),
174 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
175 ), (
177 AAAA::from_str("1::").unwrap(),
178 vec![0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
179 ),
180 (
181 AAAA::from_str("0:1::").unwrap(),
182 vec![0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
183 ),
184 (
185 AAAA::from_str("0:0:1::").unwrap(),
186 vec![0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
187 ),
188 (
189 AAAA::from_str("0:0:0:1::").unwrap(),
190 vec![0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
191 ),
192 (
193 AAAA::from_str("::1:0:0:0").unwrap(),
194 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
195 ),
196 (
197 AAAA::from_str("::1:0:0").unwrap(),
198 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
199 ),
200 (
201 AAAA::from_str("::1:0").unwrap(),
202 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
203 ),
204 (
205 AAAA::from_str("::1").unwrap(),
206 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
207 ),
208 (
209 AAAA::from_str("::127.0.0.1").unwrap(),
210 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1],
211 ),
212 (
213 AAAA::from_str("FF00::192.168.64.32").unwrap(),
214 vec![255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 168, 64, 32],
215 ),
216 ]
217 }
218
219 #[test]
220 fn test_read() {
221 test_read_data_set(get_data(), |mut d| AAAA::read(&mut d));
222 }
223
224 #[test]
225 fn test_emit() {
226 test_emit_data_set(get_data(), |e, d| d.emit(e));
227 }
228}