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