mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-26 11:44:54 +02:00
Introduce ParseAnyRecordData trait. (#256)
This PR introduces a new trait ParseAnyRecordData as a companion to ParseRecordData for types that can parse record data of any record type.
This commit is contained in:
+88
-1
@@ -16,7 +16,7 @@ use super::message_builder::{AdditionalBuilder, AnswerBuilder, PushError};
|
||||
use super::name::ParsedDname;
|
||||
use super::opt::{Opt, OptRecord};
|
||||
use super::question::Question;
|
||||
use super::rdata::ParseRecordData;
|
||||
use super::rdata::{ParseAnyRecordData, ParseRecordData};
|
||||
use super::record::{ComposeRecord, ParsedRecord, Record};
|
||||
use super::wire::{Composer, ParseError};
|
||||
use crate::rdata::rfc1035::Cname;
|
||||
@@ -968,6 +968,14 @@ impl<'a, Octs: Octets + ?Sized> RecordSection<'a, Octs> {
|
||||
RecordIter::new(self, true)
|
||||
}
|
||||
|
||||
/// Trades `self` for an interator over all the record.
|
||||
#[must_use]
|
||||
pub fn into_records<Data: ParseAnyRecordData<'a, Octs>>(
|
||||
self,
|
||||
) -> AnyRecordIter<'a, Octs, Data> {
|
||||
AnyRecordIter::new(self)
|
||||
}
|
||||
|
||||
/// Proceeds to the next section if there is one.
|
||||
///
|
||||
/// Returns an error if parsing has failed and the message is unusable
|
||||
@@ -1169,6 +1177,85 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//------------ AnyRecordIter -------------------------------------------------
|
||||
|
||||
/// An iterator over the records of a record section of a DNS message.
|
||||
///
|
||||
/// The iterator’s item type is the result of trying to parse a record.
|
||||
/// If parsing the record data fails, the iterator will return an
|
||||
/// error but can continue with the next record. If parsing the entire record
|
||||
/// fails the item will be an error and subsequent attempts to continue will
|
||||
/// also produce errors. This case can be distinguished from an error while
|
||||
/// parsing the record data by [`next_section`] returning an error, too.
|
||||
#[derive(Debug)]
|
||||
pub struct AnyRecordIter<'a, Octs: ?Sized, Data> {
|
||||
section: RecordSection<'a, Octs>,
|
||||
marker: PhantomData<Data>,
|
||||
}
|
||||
|
||||
impl<'a, Octs, Data> AnyRecordIter<'a, Octs, Data>
|
||||
where
|
||||
Octs: Octets + ?Sized,
|
||||
Data: ParseAnyRecordData<'a, Octs>,
|
||||
{
|
||||
/// Creates a new record iterator.
|
||||
fn new(section: RecordSection<'a, Octs>) -> Self {
|
||||
Self {
|
||||
section,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Trades the limited iterator for the full iterator.
|
||||
///
|
||||
/// The returned iterator will continue right after the last record
|
||||
/// previously returned.
|
||||
#[must_use]
|
||||
pub fn unwrap(self) -> RecordSection<'a, Octs> {
|
||||
self.section
|
||||
}
|
||||
|
||||
/// Proceeds to the next section if there is one.
|
||||
///
|
||||
/// Returns an error if parsing the message has failed. Returns
|
||||
/// `Ok(None)` if this iterator was already on the additional section.
|
||||
pub fn next_section(
|
||||
self,
|
||||
) -> Result<Option<RecordSection<'a, Octs>>, ParseError> {
|
||||
self.section.next_section()
|
||||
}
|
||||
}
|
||||
|
||||
//--- Clone
|
||||
|
||||
impl<'a, Octs: ?Sized, Data> Clone for AnyRecordIter<'a, Octs, Data> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
section: self.section,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- Iterator
|
||||
|
||||
impl<'a, Octs, Data> Iterator for AnyRecordIter<'a, Octs, Data>
|
||||
where
|
||||
Octs: Octets + ?Sized,
|
||||
Data: ParseAnyRecordData<'a, Octs>,
|
||||
{
|
||||
type Item =
|
||||
Result<Record<ParsedDname<Octs::Range<'a>>, Data>, ParseError>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let record = match self.section.next() {
|
||||
Some(Ok(record)) => record,
|
||||
Some(Err(err)) => return Some(Err(err)),
|
||||
None => return None,
|
||||
};
|
||||
Some(record.into_any_record())
|
||||
}
|
||||
}
|
||||
//============ Error Types ===================================================
|
||||
|
||||
//------------ ShortMessage --------------------------------------------------
|
||||
|
||||
+50
-7
@@ -152,15 +152,13 @@ impl<'a, T: ComposeRecordData> ComposeRecordData for &'a T {
|
||||
}
|
||||
}
|
||||
|
||||
//------------ ParseRecordData -----------------------------------------------
|
||||
//------------ ParseRecordData and ParseAllRecordData ------------------------
|
||||
|
||||
/// A record data type that can be parsed from a message.
|
||||
///
|
||||
/// When record data types are generic – typically over a domain name type –,
|
||||
/// they may not in all cases be parseable. They may still represent record
|
||||
/// data to be used when constructing the message.
|
||||
///
|
||||
/// To reflect this asymmetry, parsing of record data has its own trait.
|
||||
/// This trait allows a record data type to express whether it is able to
|
||||
/// parse record data for a specific record type. It is thus implemented by
|
||||
/// all record data types included in the [`rdata`][crate::rdata] module.
|
||||
pub trait ParseRecordData<'a, Octs: ?Sized>: RecordData + Sized {
|
||||
/// Parses the record data.
|
||||
///
|
||||
@@ -169,7 +167,7 @@ pub trait ParseRecordData<'a, Octs: ?Sized>: RecordData + Sized {
|
||||
/// `Ok(None)` if it doesn’t.
|
||||
///
|
||||
/// The `parser` is positioned at the beginning of the record data and is
|
||||
/// is limited to the length of the data. The method only needs to parse
|
||||
/// is limited to the length of the data. The function only needs to parse
|
||||
/// as much data as it needs. The caller has to make sure to deal with
|
||||
/// data remaining in the parser.
|
||||
///
|
||||
@@ -181,6 +179,32 @@ pub trait ParseRecordData<'a, Octs: ?Sized>: RecordData + Sized {
|
||||
) -> Result<Option<Self>, ParseError>;
|
||||
}
|
||||
|
||||
/// A record data type that can parse and represent any type of record.
|
||||
///
|
||||
/// While [`ParseRecordData`] allows a type to signal that it doesn’t
|
||||
/// actually cover a certain record type, this trait is for types that can
|
||||
/// parse and represent record data of any type.
|
||||
///
|
||||
/// When implementing a type for this trait, keep in mind that some record
|
||||
/// types – specifically those defined by [RFC 1035][crate::rdata::rfc1035] –
|
||||
/// can contain compressed domain names. Thus, this trait cannot be
|
||||
/// implemented by [`UnknownRecordData`] which just takes the raw data
|
||||
/// uninterpreted.
|
||||
pub trait ParseAnyRecordData<'a, Octs: ?Sized>: RecordData + Sized {
|
||||
/// Parses the record data.
|
||||
///
|
||||
/// The record data is for a record of type `rtype`.
|
||||
///
|
||||
/// The `parser` is positioned at the beginning of the record data and is
|
||||
/// is limited to the length of the data. The function only needs to parse
|
||||
/// as much data as it needs. The caller has to make sure to deal with
|
||||
/// data remaining in the parser.
|
||||
fn parse_any_rdata(
|
||||
rtype: Rtype,
|
||||
parser: &mut Parser<'a, Octs>,
|
||||
) -> Result<Self, ParseError>;
|
||||
}
|
||||
|
||||
//------------ UnknownRecordData ---------------------------------------------
|
||||
|
||||
/// A type for parsing any type of record data.
|
||||
@@ -305,6 +329,25 @@ impl<Octs> UnknownRecordData<Octs> {
|
||||
|
||||
Ok(UnknownRecordData { rtype, data })
|
||||
}
|
||||
|
||||
/// Parses any record type as unknown record data.
|
||||
///
|
||||
/// This is an associated function rather than an impl of
|
||||
/// [`ParseAnyRecordData`] because some record types must not be parsed
|
||||
/// as unknown data as they can contain compressed domain names.
|
||||
pub fn parse_any_rdata<'a, SrcOcts>(
|
||||
rtype: Rtype,
|
||||
parser: &mut Parser<'a, SrcOcts>,
|
||||
) -> Result<Self, ParseError>
|
||||
where
|
||||
SrcOcts: Octets<Range<'a> = Octs> + ?Sized + 'a,
|
||||
{
|
||||
let rdlen = parser.remaining();
|
||||
parser
|
||||
.parse_octets(rdlen)
|
||||
.map(|data| Self { rtype, data })
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
//--- OctetsFrom
|
||||
|
||||
+66
-9
@@ -18,7 +18,9 @@
|
||||
use super::cmp::CanonicalOrd;
|
||||
use super::iana::{Class, Rtype};
|
||||
use super::name::{FlattenInto, ParsedDname, ToDname};
|
||||
use super::rdata::{ComposeRecordData, ParseRecordData, RecordData};
|
||||
use super::rdata::{
|
||||
ComposeRecordData, ParseAnyRecordData, ParseRecordData, RecordData,
|
||||
};
|
||||
use super::wire::{Compose, Composer, FormError, Parse, ParseError};
|
||||
use core::cmp::Ordering;
|
||||
use core::time::Duration;
|
||||
@@ -662,9 +664,9 @@ impl RecordHeader<()> {
|
||||
}
|
||||
|
||||
impl<Octs> RecordHeader<ParsedDname<Octs>> {
|
||||
/// Parses the remainder of the record and returns it.
|
||||
/// Parses the remainder of the record if the record data type supports it.
|
||||
///
|
||||
/// The method assumes that the parsers is currently positioned right
|
||||
/// The method assumes that the parser is currently positioned right
|
||||
/// after the end of the record header. If the record data type `D`
|
||||
/// feels capable of parsing a record with a header of `self`, the
|
||||
/// method will parse the data and return a full `Record<D>`. Otherwise,
|
||||
@@ -687,6 +689,33 @@ impl<Octs> RecordHeader<ParsedDname<Octs>> {
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Parses the remainder of the record.
|
||||
///
|
||||
/// The method assumes that the parser is currently positioned right
|
||||
/// after the end of the record header.
|
||||
pub fn parse_into_any_record<'a, Src, Data>(
|
||||
self,
|
||||
parser: &mut Parser<'a, Src>,
|
||||
) -> Result<Record<ParsedDname<Octs>, Data>, ParseError>
|
||||
where
|
||||
Src: AsRef<[u8]> + ?Sized,
|
||||
Data: ParseAnyRecordData<'a, Src>,
|
||||
{
|
||||
let mut parser = parser.parse_parser(self.rdlen as usize)?;
|
||||
let res = Record::new(
|
||||
self.owner,
|
||||
self.class,
|
||||
self.ttl,
|
||||
Data::parse_any_rdata(self.rtype, &mut parser)?,
|
||||
);
|
||||
if parser.remaining() > 0 {
|
||||
return Err(ParseError::Form(FormError::new(
|
||||
"trailing data in option",
|
||||
)));
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Name: ToDname> RecordHeader<Name> {
|
||||
@@ -880,7 +909,7 @@ impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
}
|
||||
|
||||
impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
/// Creates a real resource record from the parsed record.
|
||||
/// Creates a real resource record if the record data type supports it.
|
||||
///
|
||||
/// The method is generic over a type that knows how to parse record
|
||||
/// data via the [`ParseRecordData`] trait. The record data is given to
|
||||
@@ -889,8 +918,6 @@ impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
/// the method returns `Ok(Some(_))`. It returns `Ok(None)` if the trait
|
||||
/// doesn’t know how to parse this particular record type. It returns
|
||||
/// an error if parsing fails.
|
||||
///
|
||||
/// [`ParseRecordData`]: ../rdata/trait.ParseRecordData.html
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn to_record<Data>(
|
||||
&self,
|
||||
@@ -903,7 +930,23 @@ impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
.parse_into_record(&mut self.data.clone())
|
||||
}
|
||||
|
||||
/// Trades the parsed record for a real resource record.
|
||||
/// Creates a real resource record.
|
||||
///
|
||||
/// The method is generic over a type that knows how to parse record
|
||||
/// data via the [`ParseAnyRecordData`] trait. The record data is given to
|
||||
/// this trait for parsing.
|
||||
pub fn to_any_record<Data>(
|
||||
&self,
|
||||
) -> Result<Record<ParsedDname<Octs::Range<'_>>, Data>, ParseError>
|
||||
where
|
||||
Data: ParseAnyRecordData<'a, Octs>,
|
||||
{
|
||||
self.header
|
||||
.deref_owner()
|
||||
.parse_into_any_record(&mut self.data.clone())
|
||||
}
|
||||
|
||||
/// Trades for a real resource record if the record data type supports it.
|
||||
///
|
||||
/// The method is generic over a type that knows how to parse record
|
||||
/// data via the [`ParseRecordData`] trait. The record data is given to
|
||||
@@ -912,8 +955,6 @@ impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
/// the method returns `Ok(Some(_))`. It returns `Ok(None)` if the trait
|
||||
/// doesn’t know how to parse this particular record type. It returns
|
||||
/// an error if parsing fails.
|
||||
///
|
||||
/// [`ParseRecordData`]: ../rdata/trait.ParseRecordData.html
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn into_record<Data>(
|
||||
mut self,
|
||||
@@ -923,6 +964,22 @@ impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
{
|
||||
self.header.deref_owner().parse_into_record(&mut self.data)
|
||||
}
|
||||
|
||||
/// Trades for a real resource record.
|
||||
///
|
||||
/// The method is generic over a type that knows how to parse record
|
||||
/// data via the [`ParseAnyRecordData`] trait. The record data is given to
|
||||
/// this trait for parsing. #[allow(clippy::type_complexity)]
|
||||
pub fn into_any_record<Data>(
|
||||
mut self,
|
||||
) -> Result<Record<ParsedDname<Octs::Range<'a>>, Data>, ParseError>
|
||||
where
|
||||
Data: ParseAnyRecordData<'a, Octs>,
|
||||
{
|
||||
self.header
|
||||
.deref_owner()
|
||||
.parse_into_any_record(&mut self.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Octs: Octets + ?Sized> ParsedRecord<'a, Octs> {
|
||||
|
||||
+138
-140
@@ -30,10 +30,19 @@ macro_rules! rdata_types {
|
||||
pub mod $module;
|
||||
)*
|
||||
|
||||
use crate::base::name::{ParsedDname, ToDname};
|
||||
use crate::base::wire::Composer;
|
||||
use crate::base::rdata::ComposeRecordData;
|
||||
use octseq::octets::OctetsFrom;
|
||||
use core::{fmt, hash};
|
||||
use crate::base::cmp::CanonicalOrd;
|
||||
use crate::base::iana::Rtype;
|
||||
use crate::base::name::{FlattenInto, ParsedDname, ToDname};
|
||||
use crate::base::opt::Opt;
|
||||
use crate::base::rdata::{
|
||||
ComposeRecordData, ParseAnyRecordData, ParseRecordData,
|
||||
RecordData, UnknownRecordData,
|
||||
};
|
||||
use crate::base::scan::ScannerError;
|
||||
use crate::base::wire::{Composer, ParseError};
|
||||
use octseq::octets::{Octets, OctetsFrom};
|
||||
use octseq::parse::Parser;
|
||||
|
||||
|
||||
//------------- ZoneRecordData ---------------------------------------
|
||||
@@ -71,7 +80,7 @@ macro_rules! rdata_types {
|
||||
$( $( $(
|
||||
$mtype($mtype $( < $( $mn ),* > )*),
|
||||
)* )* )*
|
||||
Unknown($crate::base::rdata::UnknownRecordData<O>),
|
||||
Unknown(UnknownRecordData<O>),
|
||||
}
|
||||
|
||||
impl<Octets: AsRef<[u8]>, Name: ToDname> ZoneRecordData<Octets, Name> {
|
||||
@@ -81,15 +90,12 @@ macro_rules! rdata_types {
|
||||
/// record types, the returned value will be of the
|
||||
/// `ZoneRecordData::Unknown(_)` variant.
|
||||
pub fn scan<S>(
|
||||
rtype: $crate::base::iana::Rtype,
|
||||
rtype: Rtype,
|
||||
scanner: &mut S
|
||||
) -> Result<Self, S::Error>
|
||||
where
|
||||
S: $crate::base::scan::Scanner<Octets = Octets, Dname = Name>
|
||||
{
|
||||
use $crate::base::rdata::UnknownRecordData;
|
||||
use $crate::base::scan::ScannerError;
|
||||
|
||||
if scanner.scan_opt_unknown_marker()? {
|
||||
UnknownRecordData::scan_without_marker(
|
||||
rtype, scanner
|
||||
@@ -98,7 +104,7 @@ macro_rules! rdata_types {
|
||||
else {
|
||||
match rtype {
|
||||
$( $( $(
|
||||
$crate::base::iana::Rtype::$mtype => {
|
||||
Rtype::$mtype => {
|
||||
$mtype::scan(
|
||||
scanner
|
||||
).map(ZoneRecordData::$mtype)
|
||||
@@ -115,17 +121,11 @@ macro_rules! rdata_types {
|
||||
}
|
||||
|
||||
impl<O, N> ZoneRecordData<O, N> {
|
||||
fn rtype(&self) -> $crate::base::iana::Rtype {
|
||||
use $crate::base::rdata::RecordData;
|
||||
|
||||
fn rtype(&self) -> Rtype {
|
||||
match *self {
|
||||
$( $( $(
|
||||
ZoneRecordData::$mtype(ref inner) => {
|
||||
inner.rtype()
|
||||
/*
|
||||
<$mtype $( < $( $mn ),* > )*
|
||||
as $crate::base::rdata::RtypeRecordData>::RTYPE
|
||||
*/
|
||||
}
|
||||
)* )* )*
|
||||
ZoneRecordData::Unknown(ref inner) => inner.rtype(),
|
||||
@@ -135,21 +135,21 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- OctetsFrom
|
||||
|
||||
impl<Octets, SrcOctets, Name, SrcName>
|
||||
octseq::octets::OctetsFrom<
|
||||
ZoneRecordData<SrcOctets, SrcName>
|
||||
impl<Octs, SrcOcts, Name, SrcName>
|
||||
OctetsFrom<
|
||||
ZoneRecordData<SrcOcts, SrcName>
|
||||
>
|
||||
for ZoneRecordData<Octets, Name>
|
||||
for ZoneRecordData<Octs, Name>
|
||||
where
|
||||
Octets: octseq::octets::OctetsFrom<SrcOctets>,
|
||||
Name: octseq::octets::OctetsFrom<
|
||||
SrcName, Error = Octets::Error
|
||||
Octs: OctetsFrom<SrcOcts>,
|
||||
Name: OctetsFrom<
|
||||
SrcName, Error = Octs::Error
|
||||
>,
|
||||
{
|
||||
type Error = Octets::Error;
|
||||
type Error = Octs::Error;
|
||||
|
||||
fn try_octets_from(
|
||||
source: ZoneRecordData<SrcOctets, SrcName>
|
||||
source: ZoneRecordData<SrcOcts, SrcName>
|
||||
) -> Result<Self, Self::Error> {
|
||||
match source {
|
||||
$( $( $(
|
||||
@@ -161,7 +161,6 @@ macro_rules! rdata_types {
|
||||
)* )* )*
|
||||
ZoneRecordData::Unknown(inner) => {
|
||||
Ok(ZoneRecordData::Unknown(
|
||||
$crate::base::rdata::
|
||||
UnknownRecordData::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
@@ -171,24 +170,21 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- FlattenInto
|
||||
|
||||
impl<Octets, TargetOctets, Name, TargetName>
|
||||
crate::base::name::FlattenInto<
|
||||
ZoneRecordData<TargetOctets, TargetName>
|
||||
impl<Octs, TargetOcts, Name, TargetName>
|
||||
FlattenInto<
|
||||
ZoneRecordData<TargetOcts, TargetName>
|
||||
>
|
||||
for ZoneRecordData<Octets, Name>
|
||||
for ZoneRecordData<Octs, Name>
|
||||
where
|
||||
TargetOctets: OctetsFrom<Octets>,
|
||||
Name: crate::base::name::FlattenInto<
|
||||
TargetName,
|
||||
AppendError = TargetOctets::Error,
|
||||
>,
|
||||
TargetOcts: OctetsFrom<Octs>,
|
||||
Name: FlattenInto<TargetName, AppendError = TargetOcts::Error>,
|
||||
{
|
||||
type AppendError = TargetOctets::Error;
|
||||
type AppendError = TargetOcts::Error;
|
||||
|
||||
fn try_flatten_into(
|
||||
self
|
||||
) -> Result<
|
||||
ZoneRecordData<TargetOctets, TargetName>,
|
||||
ZoneRecordData<TargetOcts, TargetName>,
|
||||
Self::AppendError
|
||||
> {
|
||||
match self {
|
||||
@@ -201,7 +197,6 @@ macro_rules! rdata_types {
|
||||
)* )* )*
|
||||
ZoneRecordData::Unknown(inner) => {
|
||||
Ok(ZoneRecordData::Unknown(
|
||||
$crate::base::rdata::
|
||||
UnknownRecordData::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
@@ -220,9 +215,9 @@ macro_rules! rdata_types {
|
||||
}
|
||||
)* )* )*
|
||||
|
||||
impl<O, N> From<$crate::base::rdata::UnknownRecordData<O>>
|
||||
impl<O, N> From<UnknownRecordData<O>>
|
||||
for ZoneRecordData<O, N> {
|
||||
fn from(value: $crate::base::rdata::UnknownRecordData<O>) -> Self {
|
||||
fn from(value: UnknownRecordData<O>) -> Self {
|
||||
ZoneRecordData::Unknown(value)
|
||||
}
|
||||
}
|
||||
@@ -234,7 +229,7 @@ macro_rules! rdata_types {
|
||||
for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>, OO: AsRef<[u8]>,
|
||||
N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname,
|
||||
N: ToDname, NN: ToDname,
|
||||
{
|
||||
fn eq(&self, other: &ZoneRecordData<OO, NN>) -> bool {
|
||||
match (self, other) {
|
||||
@@ -259,7 +254,7 @@ macro_rules! rdata_types {
|
||||
}
|
||||
|
||||
impl<O, N> Eq for ZoneRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: $crate::base::name::ToDname { }
|
||||
where O: AsRef<[u8]>, N: ToDname { }
|
||||
|
||||
|
||||
//--- PartialOrd, Ord, and CanonicalOrd
|
||||
@@ -268,7 +263,7 @@ macro_rules! rdata_types {
|
||||
for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>, OO: AsRef<[u8]>,
|
||||
N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname,
|
||||
N: ToDname, NN: ToDname,
|
||||
{
|
||||
fn partial_cmp(
|
||||
&self,
|
||||
@@ -296,13 +291,12 @@ macro_rules! rdata_types {
|
||||
}
|
||||
|
||||
impl<O, OO, N, NN>
|
||||
$crate::base::cmp::CanonicalOrd<ZoneRecordData<OO, NN>>
|
||||
CanonicalOrd<ZoneRecordData<OO, NN>>
|
||||
for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>, OO: AsRef<[u8]>,
|
||||
N: $crate::base::cmp::CanonicalOrd<NN>
|
||||
+ $crate::base::name::ToDname,
|
||||
NN: $crate::base::name::ToDname,
|
||||
N: CanonicalOrd<NN> + ToDname,
|
||||
NN: ToDname,
|
||||
{
|
||||
fn canonical_cmp(
|
||||
&self,
|
||||
@@ -331,13 +325,13 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- Hash
|
||||
|
||||
impl<O, N> core::hash::Hash for ZoneRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: core::hash::Hash {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl<O, N> hash::Hash for ZoneRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: hash::Hash {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
match *self {
|
||||
$( $( $(
|
||||
ZoneRecordData::$mtype(ref inner) => {
|
||||
$crate::base::iana::Rtype::$mtype.hash(state);
|
||||
Rtype::$mtype.hash(state);
|
||||
inner.hash(state)
|
||||
}
|
||||
)* )* )*
|
||||
@@ -351,29 +345,29 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- RecordData, ParseRecordData, and ComposeRecordData
|
||||
|
||||
impl<O, N> $crate::base::rdata::RecordData for ZoneRecordData<O, N> {
|
||||
fn rtype(&self) -> $crate::base::iana::Rtype {
|
||||
impl<O, N> RecordData for ZoneRecordData<O, N> {
|
||||
fn rtype(&self) -> Rtype {
|
||||
ZoneRecordData::rtype(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Octs: octseq::octets::Octets + ?Sized>
|
||||
$crate::base::rdata::ParseRecordData<'a, Octs>
|
||||
impl<'a, Octs: Octets + ?Sized>
|
||||
ParseRecordData<'a, Octs>
|
||||
for ZoneRecordData<Octs::Range<'a>, ParsedDname<Octs::Range<'a>>> {
|
||||
fn parse_rdata(
|
||||
rtype: $crate::base::iana::Rtype,
|
||||
parser: &mut octseq::parse::Parser<'a, Octs>,
|
||||
) -> Result<Option<Self>, $crate::base::wire::ParseError> {
|
||||
rtype: Rtype,
|
||||
parser: &mut Parser<'a, Octs>,
|
||||
) -> Result<Option<Self>, ParseError> {
|
||||
match rtype {
|
||||
$( $( $(
|
||||
$crate::base::iana::Rtype::$mtype => {
|
||||
Rtype::$mtype => {
|
||||
Ok(Some(ZoneRecordData::$mtype(
|
||||
$mtype::parse(parser)?
|
||||
)))
|
||||
}
|
||||
)* )* )*
|
||||
_ => {
|
||||
Ok($crate::base::rdata::UnknownRecordData::parse_rdata(
|
||||
Ok(UnknownRecordData::parse_rdata(
|
||||
rtype, parser
|
||||
)?.map(ZoneRecordData::Unknown))
|
||||
}
|
||||
@@ -430,13 +424,12 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- Display
|
||||
|
||||
impl<O, N> core::fmt::Display for ZoneRecordData<O, N>
|
||||
impl<O, N> fmt::Display for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>,
|
||||
N: core::fmt::Display
|
||||
N: fmt::Display
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter)
|
||||
-> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
ZoneRecordData::$mtype(ref inner) => {
|
||||
@@ -450,13 +443,12 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- Debug
|
||||
|
||||
impl<O, N> core::fmt::Debug for ZoneRecordData<O, N>
|
||||
impl<O, N> fmt::Debug for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>,
|
||||
N: core ::fmt::Debug
|
||||
N: fmt::Debug
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter)
|
||||
-> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
ZoneRecordData::$mtype(ref inner) => {
|
||||
@@ -495,14 +487,12 @@ macro_rules! rdata_types {
|
||||
$( $( $(
|
||||
$ptype($ptype $( < $( $pn ),* > )*),
|
||||
)* )* )*
|
||||
Opt($crate::base::opt::Opt<O>),
|
||||
Unknown($crate::base::rdata::UnknownRecordData<O>),
|
||||
Opt(Opt<O>),
|
||||
Unknown(UnknownRecordData<O>),
|
||||
}
|
||||
|
||||
impl<O, N> AllRecordData<O, N> {
|
||||
fn rtype(&self) -> $crate::base::iana::Rtype {
|
||||
use $crate::base::rdata::RecordData;
|
||||
|
||||
fn rtype(&self) -> Rtype {
|
||||
match *self {
|
||||
$( $( $(
|
||||
AllRecordData::$mtype(ref inner) => {
|
||||
@@ -515,7 +505,7 @@ macro_rules! rdata_types {
|
||||
}
|
||||
)* )* )*
|
||||
|
||||
AllRecordData::Opt(_) => $crate::base::iana::Rtype::Opt,
|
||||
AllRecordData::Opt(_) => Rtype::Opt,
|
||||
AllRecordData::Unknown(ref inner) => inner.rtype(),
|
||||
}
|
||||
}
|
||||
@@ -541,16 +531,16 @@ macro_rules! rdata_types {
|
||||
}
|
||||
)* )* )*
|
||||
|
||||
impl<O, N> From<$crate::base::opt::Opt<O>> for AllRecordData<O, N> {
|
||||
fn from(value: $crate::base::opt::Opt<O>) -> Self {
|
||||
impl<O, N> From<Opt<O>> for AllRecordData<O, N> {
|
||||
fn from(value: Opt<O>) -> Self {
|
||||
AllRecordData::Opt(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<O, N> From<$crate::base::rdata::UnknownRecordData<O>>
|
||||
impl<O, N> From<UnknownRecordData<O>>
|
||||
for AllRecordData<O, N> {
|
||||
fn from(
|
||||
value: $crate::base::rdata::UnknownRecordData<O>
|
||||
value: UnknownRecordData<O>
|
||||
) -> Self {
|
||||
AllRecordData::Unknown(value)
|
||||
}
|
||||
@@ -577,21 +567,21 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- OctetsFrom
|
||||
|
||||
impl<Octets, SrcOctets, Name, SrcName>
|
||||
octseq::octets::OctetsFrom<
|
||||
AllRecordData<SrcOctets, SrcName>
|
||||
impl<Octs, SrcOcts, Name, SrcName>
|
||||
OctetsFrom<
|
||||
AllRecordData<SrcOcts, SrcName>
|
||||
>
|
||||
for AllRecordData<Octets, Name>
|
||||
for AllRecordData<Octs, Name>
|
||||
where
|
||||
Octets: octseq::octets::OctetsFrom<SrcOctets>,
|
||||
Octs: octseq::octets::OctetsFrom<SrcOcts>,
|
||||
Name: octseq::octets::OctetsFrom<
|
||||
SrcName, Error = Octets::Error,
|
||||
SrcName, Error = Octs::Error,
|
||||
>,
|
||||
{
|
||||
type Error = Octets::Error;
|
||||
type Error = Octs::Error;
|
||||
|
||||
fn try_octets_from(
|
||||
source: AllRecordData<SrcOctets, SrcName>
|
||||
source: AllRecordData<SrcOcts, SrcName>
|
||||
) -> Result<Self, Self::Error> {
|
||||
match source {
|
||||
$( $( $(
|
||||
@@ -610,13 +600,12 @@ macro_rules! rdata_types {
|
||||
)* )* )*
|
||||
AllRecordData::Opt(inner) => {
|
||||
Ok(AllRecordData::Opt(
|
||||
$crate::base::opt::Opt::try_octets_from(inner)?
|
||||
Opt::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
AllRecordData::Unknown(inner) => {
|
||||
Ok(AllRecordData::Unknown(
|
||||
$crate::base::rdata::UnknownRecordData
|
||||
::try_octets_from(inner)?
|
||||
UnknownRecordData::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -625,24 +614,21 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- FlattenInto
|
||||
|
||||
impl<Octets, TargetOctets, Name, TargetName>
|
||||
crate::base::name::FlattenInto<
|
||||
AllRecordData<TargetOctets, TargetName>
|
||||
impl<Octs, TargetOcts, Name, TargetName>
|
||||
FlattenInto<
|
||||
AllRecordData<TargetOcts, TargetName>
|
||||
>
|
||||
for AllRecordData<Octets, Name>
|
||||
for AllRecordData<Octs, Name>
|
||||
where
|
||||
TargetOctets: OctetsFrom<Octets>,
|
||||
Name: crate::base::name::FlattenInto<
|
||||
TargetName,
|
||||
AppendError = TargetOctets::Error,
|
||||
>,
|
||||
TargetOcts: OctetsFrom<Octs>,
|
||||
Name: FlattenInto<TargetName, AppendError = TargetOcts::Error>,
|
||||
{
|
||||
type AppendError = TargetOctets::Error;
|
||||
type AppendError = TargetOcts::Error;
|
||||
|
||||
fn try_flatten_into(
|
||||
self
|
||||
) -> Result<
|
||||
AllRecordData<TargetOctets, TargetName>,
|
||||
AllRecordData<TargetOcts, TargetName>,
|
||||
Self::AppendError
|
||||
> {
|
||||
match self {
|
||||
@@ -662,12 +648,11 @@ macro_rules! rdata_types {
|
||||
)* )* )*
|
||||
AllRecordData::Opt(inner) => {
|
||||
Ok(AllRecordData::Opt(
|
||||
$crate::base::opt::Opt::try_octets_from(inner)?
|
||||
Opt::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
AllRecordData::Unknown(inner) => {
|
||||
Ok(AllRecordData::Unknown(
|
||||
$crate::base::rdata::
|
||||
UnknownRecordData::try_octets_from(inner)?
|
||||
))
|
||||
}
|
||||
@@ -682,7 +667,7 @@ macro_rules! rdata_types {
|
||||
for AllRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>, OO: AsRef<[u8]>,
|
||||
N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname
|
||||
N: ToDname, NN: ToDname
|
||||
{
|
||||
fn eq(&self, other: &AllRecordData<OO, NN>) -> bool {
|
||||
match (self, other) {
|
||||
@@ -708,14 +693,14 @@ macro_rules! rdata_types {
|
||||
}
|
||||
|
||||
impl<O, N> Eq for AllRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: $crate::base::name::ToDname { }
|
||||
where O: AsRef<[u8]>, N: ToDname { }
|
||||
|
||||
|
||||
//--- Hash
|
||||
|
||||
impl<O, N> core::hash::Hash for AllRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: core::hash::Hash {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
impl<O, N> hash::Hash for AllRecordData<O, N>
|
||||
where O: AsRef<[u8]>, N: hash::Hash {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.rtype().hash(state);
|
||||
match *self {
|
||||
$( $( $(
|
||||
@@ -740,8 +725,8 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- RecordData and ParseRecordData
|
||||
|
||||
impl<O, N> $crate::base::rdata::RecordData for AllRecordData<O, N> {
|
||||
fn rtype(&self) -> $crate::base::iana::Rtype {
|
||||
impl<O, N> RecordData for AllRecordData<O, N> {
|
||||
fn rtype(&self) -> Rtype {
|
||||
match *self {
|
||||
$( $( $(
|
||||
AllRecordData::$mtype(ref inner) => {
|
||||
@@ -759,42 +744,55 @@ macro_rules! rdata_types {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Octs: octseq::octets::Octets>
|
||||
$crate::base::rdata::ParseRecordData<'a, Octs>
|
||||
impl<'a, Octs: Octets>
|
||||
ParseAnyRecordData<'a, Octs>
|
||||
for AllRecordData<Octs::Range<'a>, ParsedDname<Octs::Range<'a>>> {
|
||||
fn parse_rdata(
|
||||
rtype: $crate::base::iana::Rtype,
|
||||
parser: &mut octseq::parse::Parser<'a, Octs>,
|
||||
) -> Result<Option<Self>, crate::base::wire::ParseError> {
|
||||
fn parse_any_rdata(
|
||||
rtype: Rtype,
|
||||
parser: &mut Parser<'a, Octs>,
|
||||
) -> Result<Self, ParseError> {
|
||||
match rtype {
|
||||
$( $( $(
|
||||
$crate::base::iana::Rtype::$mtype => {
|
||||
Ok(Some(AllRecordData::$mtype(
|
||||
Rtype::$mtype => {
|
||||
Ok(AllRecordData::$mtype(
|
||||
$mtype::parse(parser)?
|
||||
)))
|
||||
))
|
||||
}
|
||||
)* )* )*
|
||||
$( $( $(
|
||||
$crate::base::iana::Rtype::$ptype => {
|
||||
Ok(Some(AllRecordData::$ptype(
|
||||
Rtype::$ptype => {
|
||||
Ok(AllRecordData::$ptype(
|
||||
$ptype::parse(parser)?
|
||||
)))
|
||||
))
|
||||
}
|
||||
)* )* )*
|
||||
$crate::base::iana::Rtype::Opt => {
|
||||
Ok(Some(AllRecordData::Opt(
|
||||
$crate::base::opt::Opt::parse(parser)?
|
||||
)))
|
||||
Ok(AllRecordData::Opt(
|
||||
Opt::parse(parser)?
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
Ok($crate::base::rdata::UnknownRecordData::parse_rdata(
|
||||
rtype, parser
|
||||
)?.map(AllRecordData::Unknown))
|
||||
Ok(AllRecordData::Unknown(
|
||||
UnknownRecordData::parse_any_rdata(
|
||||
rtype, parser
|
||||
)?
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Octs: Octets>
|
||||
ParseRecordData<'a, Octs>
|
||||
for AllRecordData<Octs::Range<'a>, ParsedDname<Octs::Range<'a>>> {
|
||||
fn parse_rdata(
|
||||
rtype: Rtype,
|
||||
parser: &mut Parser<'a, Octs>,
|
||||
) -> Result<Option<Self>, ParseError> {
|
||||
ParseAnyRecordData::parse_any_rdata(rtype, parser).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Octs, Name> ComposeRecordData for AllRecordData<Octs, Name>
|
||||
where Octs: AsRef<[u8]>, Name: ToDname {
|
||||
fn rdlen(&self, compress: bool) -> Option<u16> {
|
||||
@@ -868,11 +866,11 @@ macro_rules! rdata_types {
|
||||
|
||||
//--- Display and Debug
|
||||
|
||||
impl<O, N> core::fmt::Display for AllRecordData<O, N>
|
||||
where O: octseq::octets::Octets, N: core::fmt::Display {
|
||||
impl<O, N> fmt::Display for AllRecordData<O, N>
|
||||
where O: Octets, N: fmt::Display {
|
||||
fn fmt(
|
||||
&self, f: &mut core::fmt::Formatter
|
||||
) -> core::fmt::Result {
|
||||
&self, f: &mut fmt::Formatter
|
||||
) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
AllRecordData::$mtype(ref inner) => {
|
||||
@@ -890,11 +888,11 @@ macro_rules! rdata_types {
|
||||
}
|
||||
}
|
||||
|
||||
impl<O, N> core::fmt::Debug for AllRecordData<O, N>
|
||||
where O: octseq::octets::Octets, N: core::fmt::Debug {
|
||||
impl<O, N> fmt::Debug for AllRecordData<O, N>
|
||||
where O: Octets, N: fmt::Debug {
|
||||
fn fmt(
|
||||
&self, f: &mut core::fmt::Formatter
|
||||
) -> core::fmt::Result {
|
||||
&self, f: &mut fmt::Formatter
|
||||
) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
AllRecordData::$mtype(ref inner) => {
|
||||
@@ -905,7 +903,7 @@ macro_rules! rdata_types {
|
||||
"("
|
||||
)
|
||||
)?;
|
||||
core::fmt::Debug::fmt(inner, f)?;
|
||||
fmt::Debug::fmt(inner, f)?;
|
||||
f.write_str(")")
|
||||
}
|
||||
)* )* )*
|
||||
@@ -918,18 +916,18 @@ macro_rules! rdata_types {
|
||||
"("
|
||||
)
|
||||
)?;
|
||||
core::fmt::Debug::fmt(inner, f)?;
|
||||
fmt::Debug::fmt(inner, f)?;
|
||||
f.write_str(")")
|
||||
}
|
||||
)* )* )*
|
||||
AllRecordData::Opt(ref inner) => {
|
||||
f.write_str("AllRecordData::Opt(")?;
|
||||
core::fmt::Debug::fmt(inner, f)?;
|
||||
fmt::Debug::fmt(inner, f)?;
|
||||
f.write_str(")")
|
||||
}
|
||||
AllRecordData::Unknown(ref inner) => {
|
||||
f.write_str("AllRecordData::Unknown(")?;
|
||||
core::fmt::Debug::fmt(inner, f)?;
|
||||
fmt::Debug::fmt(inner, f)?;
|
||||
f.write_str(")")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user