1use alloc::string::ToString;
27pub use core::net::Ipv6Addr;
28use core::{
29 fmt,
30 net::AddrParseError,
31 ops::Deref,
32 str::{self, FromStr},
33};
34
35#[cfg(feature = "serde")]
36use serde::{Deserialize, Serialize};
37
38use crate::{
39 error::ProtoResult,
40 rr::{RData, RecordData, RecordType},
41 serialize::{
42 binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder, DecodeError},
43 txt::ParseError,
44 },
45};
46
47#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
49#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
50pub struct AAAA(pub Ipv6Addr);
51
52impl AAAA {
53 #[allow(clippy::too_many_arguments)]
55 pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Self {
56 Self(Ipv6Addr::new(a, b, c, d, e, f, g, h))
57 }
58
59 pub(crate) fn from_tokens<'i, I: Iterator<Item = &'i str>>(
61 mut tokens: I,
62 ) -> Result<Self, ParseError> {
63 let address: Ipv6Addr = tokens
64 .next()
65 .ok_or_else(|| ParseError::MissingToken("ipv6 address".to_string()))
66 .and_then(|s| Ipv6Addr::from_str(s).map_err(Into::into))?;
67 Ok(address.into())
68 }
69}
70
71impl RecordData for AAAA {
72 fn try_borrow(data: &RData) -> Option<&Self> {
73 match data {
74 RData::AAAA(ipv6) => Some(ipv6),
75 _ => None,
76 }
77 }
78
79 fn record_type(&self) -> RecordType {
80 RecordType::AAAA
81 }
82
83 fn into_rdata(self) -> RData {
84 RData::AAAA(self)
85 }
86}
87
88impl BinEncodable for AAAA {
89 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
90 let segments = self.segments();
91
92 encoder.emit_u16(segments[0])?;
94 encoder.emit_u16(segments[1])?;
95 encoder.emit_u16(segments[2])?;
96 encoder.emit_u16(segments[3])?;
97 encoder.emit_u16(segments[4])?;
98 encoder.emit_u16(segments[5])?;
99 encoder.emit_u16(segments[6])?;
100 encoder.emit_u16(segments[7])?;
101 Ok(())
102 }
103}
104
105impl<'r> BinDecodable<'r> for AAAA {
106 fn read(decoder: &mut BinDecoder<'r>) -> Result<Self, DecodeError> {
107 let a: u16 = decoder.read_u16()?.unverified();
109 let b: u16 = decoder.read_u16()?.unverified();
110 let c: u16 = decoder.read_u16()?.unverified();
111 let d: u16 = decoder.read_u16()?.unverified();
112 let e: u16 = decoder.read_u16()?.unverified();
113 let f: u16 = decoder.read_u16()?.unverified();
114 let g: u16 = decoder.read_u16()?.unverified();
115 let h: u16 = decoder.read_u16()?.unverified();
116
117 Ok(Ipv6Addr::new(a, b, c, d, e, f, g, h).into())
118 }
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 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 alloc::vec::Vec;
157 use core::str::FromStr;
158
159 use super::*;
160 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
161
162 fn get_data() -> Vec<(AAAA, Vec<u8>)> {
163 vec![
164 (
165 AAAA::from_str("::").unwrap(),
166 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
167 ), (
169 AAAA::from_str("1::").unwrap(),
170 vec![0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
171 ),
172 (
173 AAAA::from_str("0:1::").unwrap(),
174 vec![0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
175 ),
176 (
177 AAAA::from_str("0:0:1::").unwrap(),
178 vec![0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
179 ),
180 (
181 AAAA::from_str("0:0:0:1::").unwrap(),
182 vec![0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
183 ),
184 (
185 AAAA::from_str("::1:0:0:0").unwrap(),
186 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
187 ),
188 (
189 AAAA::from_str("::1:0:0").unwrap(),
190 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
191 ),
192 (
193 AAAA::from_str("::1:0").unwrap(),
194 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
195 ),
196 (
197 AAAA::from_str("::1").unwrap(),
198 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
199 ),
200 (
201 AAAA::from_str("::127.0.0.1").unwrap(),
202 vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1],
203 ),
204 (
205 AAAA::from_str("FF00::192.168.64.32").unwrap(),
206 vec![255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 168, 64, 32],
207 ),
208 ]
209 }
210
211 #[test]
212 fn test_read() {
213 test_read_data_set(get_data(), |mut d| AAAA::read(&mut d));
214 }
215
216 #[test]
217 fn test_emit() {
218 test_emit_data_set(get_data(), |e, d| d.emit(e));
219 }
220}