use core::cmp::Ordering;
use crate::new::base::build::{BuildInMessage, NameCompressor};
use crate::new::base::name::CanonicalName;
use crate::new::base::parse::{ParseMessageBytes, SplitMessageBytes};
use crate::new::base::{
wire::*, CanonicalRecordData, ParseRecordData, ParseRecordDataBytes,
RType,
};
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
Hash,
BuildBytes,
ParseBytes,
SplitBytes,
)]
pub struct Rp<N> {
pub mailbox: N,
pub texts: N,
}
impl<N> Rp<N> {
pub fn map_names<R, F: FnMut(N) -> R>(self, mut f: F) -> Rp<R> {
Rp {
mailbox: (f)(self.mailbox),
texts: (f)(self.texts),
}
}
pub fn map_names_by_ref<'r, R, F: FnMut(&'r N) -> R>(
&'r self,
mut f: F,
) -> Rp<R> {
Rp {
mailbox: (f)(&self.mailbox),
texts: (f)(&self.texts),
}
}
}
impl<N: CanonicalName> CanonicalRecordData for Rp<N> {
fn build_canonical_bytes<'b>(
&self,
bytes: &'b mut [u8],
) -> Result<&'b mut [u8], TruncationError> {
let bytes = self.mailbox.build_lowercased_bytes(bytes)?;
let bytes = self.texts.build_lowercased_bytes(bytes)?;
Ok(bytes)
}
fn cmp_canonical(&self, other: &Self) -> Ordering {
self.mailbox
.cmp_lowercase_composed(&other.mailbox)
.then_with(|| self.texts.cmp_lowercase_composed(&other.texts))
}
}
impl<'a, N: SplitMessageBytes<'a>> ParseMessageBytes<'a> for Rp<N> {
fn parse_message_bytes(
contents: &'a [u8],
start: usize,
) -> Result<Self, ParseError> {
let (mailbox, rest) = N::split_message_bytes(contents, start)?;
let texts = N::parse_message_bytes(contents, rest)?;
Ok(Self { mailbox, texts })
}
}
impl<N: BuildInMessage> BuildInMessage for Rp<N> {
fn build_in_message(
&self,
contents: &mut [u8],
mut start: usize,
compressor: &mut NameCompressor,
) -> Result<usize, TruncationError> {
start = self.mailbox.build_in_message(contents, start, compressor)?;
start = self.texts.build_in_message(contents, start, compressor)?;
Ok(start)
}
}
impl<'a, N: SplitMessageBytes<'a>> ParseRecordData<'a> for Rp<N> {
fn parse_record_data(
contents: &'a [u8],
start: usize,
rtype: RType,
) -> Result<Self, ParseError> {
match rtype {
RType::RP => Self::parse_message_bytes(contents, start),
_ => Err(ParseError),
}
}
}
impl<'a, N: SplitBytes<'a>> ParseRecordDataBytes<'a> for Rp<N> {
fn parse_record_data_bytes(
bytes: &'a [u8],
rtype: RType,
) -> Result<Self, ParseError> {
match rtype {
RType::RP => Self::parse_bytes(bytes),
_ => Err(ParseError),
}
}
}