1#[cfg(not(feature = "std"))]
35use core::net::AddrParseError;
36use core::{fmt, ops::Deref, str};
37#[cfg(feature = "std")]
38use std::net::AddrParseError;
39
40#[cfg(not(feature = "std"))]
41pub use core::net::Ipv4Addr;
42#[cfg(feature = "std")]
43pub use std::net::Ipv4Addr;
44
45#[cfg(feature = "serde")]
46use serde::{Deserialize, Serialize};
47
48use crate::{
49 error::*,
50 rr::{RData, RecordData, RecordType},
51 serialize::binary::*,
52};
53
54#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
56#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
57pub struct A(pub Ipv4Addr);
58
59impl A {
60 pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Self {
62 Self(Ipv4Addr::new(a, b, c, d))
63 }
64}
65
66impl RecordData for A {
67 fn try_from_rdata(data: RData) -> Result<Self, crate::rr::RData> {
68 match data {
69 RData::A(ipv4) => Ok(ipv4),
70 _ => Err(data),
71 }
72 }
73
74 fn try_borrow(data: &RData) -> Option<&Self> {
75 match data {
76 RData::A(ipv4) => Some(ipv4),
77 _ => None,
78 }
79 }
80
81 fn record_type(&self) -> RecordType {
82 RecordType::A
83 }
84
85 fn into_rdata(self) -> RData {
86 RData::A(self)
87 }
88}
89
90impl BinEncodable for A {
91 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
92 let segments = self.octets();
93
94 encoder.emit(segments[0])?;
95 encoder.emit(segments[1])?;
96 encoder.emit(segments[2])?;
97 encoder.emit(segments[3])?;
98 Ok(())
99 }
100}
101
102impl<'r> BinDecodable<'r> for A {
103 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
104 Ok(Ipv4Addr::new(
106 decoder.pop()?.unverified(),
107 decoder.pop()?.unverified(),
108 decoder.pop()?.unverified(),
109 decoder.pop()?.unverified(),
110 )
111 .into())
112 }
113}
114
115#[deprecated(note = "use the BinDecodable::read method instead")]
117pub fn read(decoder: &mut BinDecoder<'_>) -> ProtoResult<A> {
118 <A as BinDecodable>::read(decoder)
119}
120
121#[deprecated(note = "use the BinEncodable::emit method instead")]
123pub fn emit(encoder: &mut BinEncoder<'_>, address: Ipv4Addr) -> ProtoResult<()> {
124 BinEncodable::emit(&A::from(address), encoder)
125}
126
127impl From<Ipv4Addr> for A {
128 fn from(a: Ipv4Addr) -> Self {
129 Self(a)
130 }
131}
132
133impl From<A> for Ipv4Addr {
134 fn from(a: A) -> Self {
135 a.0
136 }
137}
138
139impl Deref for A {
140 type Target = Ipv4Addr;
141
142 fn deref(&self) -> &Self::Target {
143 &self.0
144 }
145}
146
147impl fmt::Display for A {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
149 write!(f, "{}", self.0)
150 }
151}
152
153impl str::FromStr for A {
154 type Err = AddrParseError;
155 fn from_str(s: &str) -> Result<Self, AddrParseError> {
156 Ipv4Addr::from_str(s).map(From::from)
157 }
158}
159
160#[cfg(test)]
161mod mytests {
162 use alloc::vec::Vec;
163
164 use super::*;
165 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
166
167 fn get_data() -> Vec<(A, Vec<u8>)> {
168 vec![
169 (A::from(Ipv4Addr::UNSPECIFIED), vec![0, 0, 0, 0]), (A::from(Ipv4Addr::new(1, 0, 0, 0)), vec![1, 0, 0, 0]),
171 (A::from(Ipv4Addr::new(0, 1, 0, 0)), vec![0, 1, 0, 0]),
172 (A::from(Ipv4Addr::new(0, 0, 1, 0)), vec![0, 0, 1, 0]),
173 (A::from(Ipv4Addr::new(0, 0, 0, 1)), vec![0, 0, 0, 1]),
174 (A::from(Ipv4Addr::LOCALHOST), vec![127, 0, 0, 1]),
175 (
176 A::from(Ipv4Addr::new(192, 168, 64, 32)),
177 vec![192, 168, 64, 32],
178 ),
179 ]
180 }
181
182 #[test]
183 fn test_parse() {
184 test_read_data_set(get_data(), |mut d| A::read(&mut d));
185 }
186
187 #[test]
188 fn test_write_to() {
189 test_emit_data_set(get_data(), |e, d| d.emit(e));
190 }
191}