use core::cmp::Ordering;
use core::fmt;
use core::net::Ipv6Addr;
use core::str::FromStr;
use crate::new::base::build::{
BuildInMessage, NameCompressor, TruncationError,
};
use crate::new::base::parse::ParseMessageBytes;
use crate::new::base::wire::{
AsBytes, BuildBytes, ParseBytes, ParseBytesZC, ParseError, SplitBytes,
SplitBytesZC,
};
use crate::new::base::{
CanonicalRecordData, ParseRecordData, ParseRecordDataBytes, RType,
};
use crate::utils::dst::UnsizedCopy;
#[derive(
Copy,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
AsBytes,
BuildBytes,
ParseBytes,
ParseBytesZC,
SplitBytes,
SplitBytesZC,
UnsizedCopy,
)]
#[repr(transparent)]
pub struct Aaaa {
pub octets: [u8; 16],
}
impl From<Ipv6Addr> for Aaaa {
fn from(value: Ipv6Addr) -> Self {
Self {
octets: value.octets(),
}
}
}
impl From<Aaaa> for Ipv6Addr {
fn from(value: Aaaa) -> Self {
Self::from(value.octets)
}
}
impl CanonicalRecordData for Aaaa {
fn cmp_canonical(&self, other: &Self) -> Ordering {
self.octets.cmp(&other.octets)
}
}
impl FromStr for Aaaa {
type Err = <Ipv6Addr as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ipv6Addr::from_str(s).map(Aaaa::from)
}
}
impl fmt::Debug for Aaaa {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Aaaa({self})")
}
}
impl fmt::Display for Aaaa {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ipv6Addr::from(*self).fmt(f)
}
}
impl ParseMessageBytes<'_> for Aaaa {
fn parse_message_bytes(
contents: &'_ [u8],
start: usize,
) -> Result<Self, ParseError> {
contents
.get(start..)
.ok_or(ParseError)
.and_then(Self::parse_bytes)
}
}
impl BuildInMessage for Aaaa {
fn build_in_message(
&self,
contents: &mut [u8],
start: usize,
_compressor: &mut NameCompressor,
) -> Result<usize, TruncationError> {
let end = start + self.octets.len();
let bytes = contents.get_mut(start..end).ok_or(TruncationError)?;
bytes.copy_from_slice(&self.octets);
Ok(end)
}
}
impl ParseRecordData<'_> for Aaaa {}
impl ParseRecordDataBytes<'_> for Aaaa {
fn parse_record_data_bytes(
bytes: &'_ [u8],
rtype: RType,
) -> Result<Self, ParseError> {
match rtype {
RType::AAAA => Self::parse_bytes(bytes),
_ => Err(ParseError),
}
}
}
impl<'a> ParseRecordData<'a> for &'a Aaaa {}
impl<'a> ParseRecordDataBytes<'a> for &'a Aaaa {
fn parse_record_data_bytes(
bytes: &'a [u8],
rtype: RType,
) -> Result<Self, ParseError> {
match rtype {
RType::AAAA => Self::parse_bytes(bytes),
_ => Err(ParseError),
}
}
}