mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-07 18:37:46 +02:00
add Present trait for printing Records as zonefile
This commit is contained in:
+48
-1
@@ -201,6 +201,24 @@ macro_rules! int_enum_str_decimal {
|
||||
|
||||
impl core::fmt::Display for $ianatype {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
use std::fmt::Write;
|
||||
|
||||
write!(f, "{}", self.to_int())?;
|
||||
|
||||
if let Some(m) = self.to_mnemonic() {
|
||||
write!(f, "(")?;
|
||||
for ch in m {
|
||||
f.write_char(*ch as char)?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::zonefile::present::Present for $ianatype {
|
||||
fn present(&self, f: &mut $crate::zonefile::present::ZoneFileFormatter) -> core::fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}", self.to_int())
|
||||
}
|
||||
}
|
||||
@@ -275,6 +293,26 @@ macro_rules! int_enum_str_with_decimal {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
use core::fmt::Write;
|
||||
|
||||
match self.to_mnemonic() {
|
||||
Some(m) => {
|
||||
for ch in m {
|
||||
f.write_char(*ch as char)?
|
||||
}
|
||||
write!(f, "({})", self.to_int())
|
||||
}
|
||||
None => {
|
||||
write!(f, "{}", self.to_int())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::zonefile::present::Present for $ianatype {
|
||||
fn present(
|
||||
&self,
|
||||
f: &mut $crate::zonefile::present::ZoneFileFormatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
use std::fmt::Write;
|
||||
match self.to_mnemonic() {
|
||||
Some(m) => {
|
||||
for ch in m {
|
||||
@@ -389,7 +427,16 @@ macro_rules! int_enum_str_with_prefix {
|
||||
|
||||
impl core::fmt::Display for $ianatype {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
use core::fmt::Write;
|
||||
$crate::zonefile::present::Present::write_presentation(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::zonefile::present::Present for $ianatype {
|
||||
fn present(
|
||||
&self,
|
||||
f: &mut $crate::zonefile::present::ZoneFileFormatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
use std::fmt::Write;
|
||||
|
||||
match self.to_mnemonic() {
|
||||
Some(m) => {
|
||||
|
||||
@@ -116,4 +116,4 @@ int_enum! {
|
||||
(PRIVATEOID => 254, b"PRIVATEOID")
|
||||
}
|
||||
|
||||
int_enum_str_with_decimal!(SecAlg, u8, "unknown algorithm");
|
||||
int_enum_str_decimal!(SecAlg, u8);
|
||||
|
||||
@@ -47,6 +47,7 @@ use super::rdata::{ComposeRecordData, ParseRecordData, RecordData};
|
||||
use super::record::{Record, Ttl};
|
||||
use super::wire::{Compose, Composer, FormError, ParseError};
|
||||
use crate::utils::base16;
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::marker::PhantomData;
|
||||
use core::{fmt, hash, mem};
|
||||
@@ -358,6 +359,16 @@ impl<Octs: AsRef<[u8]> + ?Sized> fmt::Debug for Opt<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]> + ?Sized> Present for Opt<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
// XXX TODO Print this properly.
|
||||
use std::fmt::Write;
|
||||
f.write_str("OPT ...")
|
||||
}
|
||||
}
|
||||
|
||||
//------------ OptHeader -----------------------------------------------------
|
||||
|
||||
/// The header of an OPT record.
|
||||
|
||||
@@ -20,6 +20,7 @@ use super::iana::Rtype;
|
||||
use super::scan::{Scan, Scanner, ScannerError, Symbol};
|
||||
use super::wire::{Compose, Composer, ParseError};
|
||||
use crate::utils::base16;
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use octseq::octets::{Octets, OctetsFrom};
|
||||
@@ -477,6 +478,19 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for UnknownRecordData<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for UnknownRecordData<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "\\# {}", self.data.as_ref().len())?;
|
||||
for ch in self.data.as_ref() {
|
||||
write!(f, " {:02x}", *ch)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//============ Errors ========================================================
|
||||
|
||||
//------------ LongRecordData ------------------------------------------------
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
//! [`RecordHeader`]: struct.RecordHeader.html
|
||||
//! [`ParsedRecord`]: struct.ParsedRecord.html
|
||||
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
|
||||
use super::cmp::CanonicalOrd;
|
||||
use super::iana::{Class, Rtype};
|
||||
use super::name::{FlattenInto, ParsedName, ToName};
|
||||
@@ -431,6 +433,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
impl<Name, Data> Present for Record<Name, Data>
|
||||
where
|
||||
Name: fmt::Display,
|
||||
Data: RecordData + Present,
|
||||
{
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
|
||||
write!(f, "{} ", self.owner)?;
|
||||
self.ttl.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.class.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.data.rtype().present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.data.present(f)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ ComposeRecord -------------------------------------------------
|
||||
|
||||
/// A helper trait allowing construction of records on the fly.
|
||||
@@ -1481,6 +1503,13 @@ impl Ttl {
|
||||
}
|
||||
}
|
||||
|
||||
impl Present for Ttl {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}", self.as_secs())
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Add for Ttl {
|
||||
type Output = Ttl;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::net::Ipv6Addr;
|
||||
use crate::base::rdata::{ComposeRecordData, ParseRecordData, RecordData};
|
||||
use crate::base::scan::{Scanner, ScannerError};
|
||||
use crate::base::wire::{Composer, Parse, ParseError};
|
||||
use crate::zonefile::present::Present;
|
||||
use core::cmp::Ordering;
|
||||
use core::convert::Infallible;
|
||||
use core::str::FromStr;
|
||||
@@ -156,6 +157,15 @@ impl fmt::Display for Aaaa {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl Present for Aaaa {
|
||||
fn present(&self, f: &mut crate::zonefile::present::ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}", self.addr)
|
||||
}
|
||||
}
|
||||
|
||||
//--- AsRef and AsMut
|
||||
|
||||
impl AsRef<Ipv6Addr> for Aaaa {
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::base::rdata::{
|
||||
use crate::base::scan::{Scan, Scanner, ScannerError};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::utils::{base16, base64};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::{fmt, hash};
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -319,6 +320,18 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Cdnskey<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Cdnskey<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{} {} ", self.flags, self.protocol)?;
|
||||
self.algorithm.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
base64::display(&self.public_key, f)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Cds -----------------------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -646,6 +659,23 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Cds<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Cds<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
f,
|
||||
"{} {} {} ",
|
||||
self.key_tag, self.algorithm, self.digest_type
|
||||
)?;
|
||||
for ch in self.digest.as_ref() {
|
||||
write!(f, "{:02x}", ch)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//------------ parsed --------------------------------------------------------
|
||||
|
||||
pub mod parsed {
|
||||
|
||||
+79
-2
@@ -15,6 +15,7 @@ use crate::base::serial::Serial;
|
||||
use crate::base::wire::{Compose, Composer, FormError, Parse, ParseError};
|
||||
use crate::base::Ttl;
|
||||
use crate::utils::{base16, base64};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::convert::TryInto;
|
||||
use core::{cmp, fmt, hash, str};
|
||||
@@ -431,6 +432,18 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Dnskey<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Dnskey<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{} {} ", self.flags, self.protocol)?;
|
||||
self.algorithm.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
base64::display(&self.public_key, f)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ ProtoRrsig ----------------------------------------------------
|
||||
|
||||
/// The RRSIG RDATA to be included when creating the signature.
|
||||
@@ -757,6 +770,15 @@ impl fmt::Display for Timestamp {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl Present for Timestamp {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
//--- PartialOrd and CanonicalOrd
|
||||
|
||||
impl cmp::PartialOrd for Timestamp {
|
||||
@@ -1354,6 +1376,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs, Name> Present for Rrsig<Octs, Name>
|
||||
where
|
||||
Octs: AsRef<[u8]>,
|
||||
Name: fmt::Display,
|
||||
{
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
self.type_covered.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.algorithm.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.original_ttl.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.expiration.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.inception.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
write!(f, " {} {}. ", self.key_tag, self.signer_name)?;
|
||||
base64::display(&self.signature, f)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Nsec ----------------------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -1634,6 +1680,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs, Name> Present for Nsec<Octs, Name>
|
||||
where
|
||||
Octs: AsRef<[u8]>,
|
||||
Name: fmt::Display,
|
||||
{
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}. {}", self.next_name, self.types)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Ds -----------------------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -1945,7 +2004,7 @@ impl<Octs: AsRef<[u8]>> fmt::Display for Ds<Octs> {
|
||||
write!(
|
||||
f,
|
||||
"{} {} {} ",
|
||||
self.key_tag, self.algorithm.to_int(), self.digest_type
|
||||
self.key_tag, self.algorithm, self.digest_type
|
||||
)?;
|
||||
for ch in self.digest.as_ref() {
|
||||
write!(f, "{:02x}", ch)?
|
||||
@@ -1967,6 +2026,24 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Ds<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Ds<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
|
||||
write!(f, "{} ", self.key_tag)?;
|
||||
self.algorithm.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
self.digest_type.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
for ch in self.digest.as_ref() {
|
||||
write!(f, "{:02x}", ch)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//------------ RtypeBitmap ---------------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -2432,7 +2509,7 @@ where
|
||||
let buf_len = self.buf.as_ref().len();
|
||||
for src_pos in (0..buf_len).step_by(34) {
|
||||
let chunk_len = (self.buf.as_ref()[src_pos + 1] as usize) + 2;
|
||||
let buf = self.buf.as_mut();
|
||||
let buf = self.buf.as_mut();
|
||||
buf.copy_within(src_pos..src_pos+chunk_len, dst_pos);
|
||||
dst_pos += chunk_len;
|
||||
}
|
||||
|
||||
@@ -499,6 +499,25 @@ macro_rules! rdata_types {
|
||||
}
|
||||
}
|
||||
|
||||
///--- Present
|
||||
|
||||
impl<O, N> $crate::zonefile::present::Present for ZoneRecordData<O, N>
|
||||
where
|
||||
O: AsRef<[u8]>,
|
||||
N: fmt::Display
|
||||
{
|
||||
fn present(&self, f: &mut $crate::zonefile::present::ZoneFileFormatter) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
ZoneRecordData::$mtype(ref inner) => {
|
||||
inner.present(f)
|
||||
}
|
||||
)* )* )*
|
||||
ZoneRecordData::Unknown(ref inner) => inner.present(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------- AllRecordData ----------------------------------------
|
||||
|
||||
/// Record data for all record types.
|
||||
@@ -1102,6 +1121,28 @@ macro_rules! rdata_types {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
impl<O, N> $crate::zonefile::present::Present for AllRecordData<O, N>
|
||||
where O: Octets, N: fmt::Display {
|
||||
fn present(
|
||||
&self, f: &mut $crate::zonefile::present::ZoneFileFormatter
|
||||
) -> fmt::Result {
|
||||
match *self {
|
||||
$( $( $(
|
||||
AllRecordData::$mtype(ref inner) => {
|
||||
inner.present(f)
|
||||
}
|
||||
)* )* )*
|
||||
$( $( $(
|
||||
AllRecordData::$ptype(ref inner) => {
|
||||
inner.present(f)
|
||||
}
|
||||
)* )* )*
|
||||
AllRecordData::Opt(ref inner) => inner.present(f),
|
||||
AllRecordData::Unknown(ref inner) => inner.present(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,6 +1329,15 @@ macro_rules! name_type_base {
|
||||
write!(f, "{}.", self.$field)
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<N: fmt::Display> $crate::zonefile::present::Present for $target<N> {
|
||||
fn present(&self, f: &mut $crate::zonefile::present::ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}.", self.$field)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::base::scan::{
|
||||
};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::utils::{base16, base32};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
#[cfg(feature = "bytes")]
|
||||
use bytes::Bytes;
|
||||
use core::cmp::Ordering;
|
||||
@@ -369,6 +370,27 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Nsec3<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Present
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Nsec3<Octs>
|
||||
where
|
||||
Octs: AsRef<[u8]>,
|
||||
{
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
|
||||
self.hash_algorithm.present(f)?;
|
||||
write!(f, " {} {} ", self.flags, self.iterations)?;
|
||||
self.salt.present(f)?;
|
||||
f.write_char(' ')?;
|
||||
base32::display_hex(&self.next_owner, f)?;
|
||||
write!(f, " {}", self.types)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Nsec3Param ----------------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -661,6 +683,17 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Nsec3param<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Nsec3param<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
self.hash_algorithm.present(f)?;
|
||||
write!(f, " {} {} ", self.flags, self.iterations)?;
|
||||
self.salt.present(f)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Nsec3Salt -----------------------------------------------------
|
||||
|
||||
/// The salt value of an NSEC3 record.
|
||||
@@ -970,6 +1003,14 @@ impl<Octs: AsRef<[u8]> + ?Sized> fmt::Debug for Nsec3Salt<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]> + ?Sized> Present for Nsec3Salt<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
base16::display(self.as_slice(), f)
|
||||
}
|
||||
}
|
||||
|
||||
//--- Serialize and Deserialize
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::rdata::{
|
||||
};
|
||||
use crate::base::scan::{Scanner, ScannerError};
|
||||
use crate::base::wire::{Composer, Parse, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::{fmt, str};
|
||||
use core::cmp::Ordering;
|
||||
use core::convert::Infallible;
|
||||
@@ -172,6 +173,15 @@ impl fmt::Display for A {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Display
|
||||
|
||||
impl Present for A {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}", self.addr)
|
||||
}
|
||||
}
|
||||
|
||||
//--- AsRef and AsMut
|
||||
|
||||
impl AsRef<Ipv4Addr> for A {
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::rdata::{
|
||||
};
|
||||
use crate::base::scan::Scanner;
|
||||
use crate::base::wire::{Composer, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::{fmt, hash};
|
||||
use core::cmp::Ordering;
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -236,6 +237,15 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Hinfo<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Hinfo<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{} {}", self.cpu, self.os)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing =======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::rdata::{
|
||||
};
|
||||
use crate::base::scan::Scanner;
|
||||
use crate::base::wire::{Composer, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::fmt;
|
||||
use core::cmp::Ordering;
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -242,6 +243,15 @@ impl<N: fmt::Display> fmt::Display for Minfo<N> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<N: fmt::Display> Present for Minfo<N> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{}. {}.", self.rmailbx, self.emailbx)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing =======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::rdata::{
|
||||
};
|
||||
use crate::base::scan::{Scan, Scanner};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::fmt;
|
||||
use core::cmp::Ordering;
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -227,6 +228,15 @@ impl<N: fmt::Display> fmt::Display for Mx<N> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<N: fmt::Display> Present for Mx<N> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{} {}.", self.preference, self.exchange)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing =======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::base::rdata::{
|
||||
ComposeRecordData, LongRecordData, ParseRecordData, RecordData,
|
||||
};
|
||||
use crate::base::wire::{Composer, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::{fmt, hash, mem};
|
||||
use core::cmp::Ordering;
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -277,6 +278,19 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Null<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Null<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "\\# {}", self.data.as_ref().len())?;
|
||||
for ch in self.data.as_ref().iter() {
|
||||
write!(f, " {:02x}", ch)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing =======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -12,6 +12,7 @@ use crate::base::record::Ttl;
|
||||
use crate::base::scan::{Scan, Scanner};
|
||||
use crate::base::serial::Serial;
|
||||
use crate::base::wire::{Compose, Composer, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::fmt;
|
||||
use core::cmp::Ordering;
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -401,6 +402,23 @@ impl<N: fmt::Display> fmt::Display for Soa<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> Present for Soa<N> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
f,
|
||||
"{}. {}. {} {} {} {} {}",
|
||||
self.mname,
|
||||
self.rname,
|
||||
self.serial,
|
||||
self.refresh.as_secs(),
|
||||
self.retry.as_secs(),
|
||||
self.expire.as_secs(),
|
||||
self.minimum.as_secs()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing =======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::base::scan::Scanner;
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::base::scan::Symbol;
|
||||
use crate::base::wire::{Composer, FormError, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
#[cfg(feature = "bytes")]
|
||||
use bytes::BytesMut;
|
||||
use core::cmp::Ordering;
|
||||
@@ -464,6 +465,24 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Txt<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Txt<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
let mut first = true;
|
||||
for slice in self.iter_charstrs() {
|
||||
if !first {
|
||||
f.write_str(" ")?;
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
write!(f, "{}", slice.display_quoted())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//--- Serialize and Deserialize
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::name::{FlattenInto, ParsedName, ToName};
|
||||
use crate::base::rdata::{ComposeRecordData, ParseRecordData, RecordData};
|
||||
use crate::base::scan::{Scan, Scanner};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -282,6 +283,19 @@ impl<N: fmt::Display> fmt::Display for Srv<N> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<N: fmt::Display> Present for Srv<N> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
f,
|
||||
"{} {} {} {}",
|
||||
self.priority, self.weight, self.port, self.target
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Testing ======================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::base::cmp::CanonicalOrd;
|
||||
use crate::base::iana::SvcParamKey;
|
||||
use crate::base::scan::Symbol;
|
||||
use crate::base::wire::{Compose, Parse, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use octseq::builder::{EmptyBuilder, FromBuilder, OctetsBuilder, ShortBuf};
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
use octseq::parse::{Parser, ShortInput};
|
||||
@@ -361,6 +362,36 @@ impl<Octs: Octets + ?Sized> fmt::Debug for SvcParams<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
//-- Present
|
||||
|
||||
impl<Octs: Octets + ?Sized> Present for SvcParams<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
let mut parser = Parser::from_ref(self.as_slice());
|
||||
let mut first = true;
|
||||
while parser.remaining() > 0 {
|
||||
let key = SvcParamKey::parse(
|
||||
&mut parser
|
||||
).expect("invalid SvcbParam");
|
||||
let len = usize::from(
|
||||
u16::parse(&mut parser).expect("invalid SvcParam")
|
||||
);
|
||||
let mut parser = parser.parse_parser(
|
||||
len
|
||||
).expect("invalid SvcParam");
|
||||
if first {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
write!(
|
||||
f, "{}", super::value::AllValues::parse_any(key, &mut parser)
|
||||
)?;
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//------------ ValueIter -----------------------------------------------------
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::base::rdata::{
|
||||
ComposeRecordData, LongRecordData, ParseRecordData, RecordData,
|
||||
};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
use octseq::parse::Parser;
|
||||
use core::{cmp, fmt, hash};
|
||||
@@ -464,6 +465,20 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<Variant, Octs, Name> Present for SvcbRdata<Variant, Octs, Name>
|
||||
where
|
||||
Octs: Octets,
|
||||
Name: fmt::Display,
|
||||
{
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(f, "{} {} ", self.priority, self.target)?;
|
||||
self.params.present(f)
|
||||
}
|
||||
}
|
||||
|
||||
//============ Tests =========================================================
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -12,6 +12,7 @@ use crate::base::rdata::{
|
||||
};
|
||||
use crate::base::wire::{Compose, Composer, Parse, ParseError};
|
||||
use crate::utils::base64;
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::{fmt, hash};
|
||||
use octseq::builder::OctetsBuilder;
|
||||
@@ -600,6 +601,23 @@ impl<O: AsRef<[u8]>, N: fmt::Debug> fmt::Debug for Tsig<O, N> {
|
||||
}
|
||||
}
|
||||
|
||||
//--- Present
|
||||
|
||||
impl<O: AsRef<[u8]>, N: fmt::Display> Present for Tsig<O, N> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
f,
|
||||
"{}. {} {} ",
|
||||
self.algorithm, self.time_signed, self.fudge
|
||||
)?;
|
||||
base64::display(&self.mac, f)?;
|
||||
write!(f, " {} {} \"", self.original_id, self.error)?;
|
||||
base64::display(&self.other, f)?;
|
||||
write!(f, "\"")
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Time48 --------------------------------------------------------
|
||||
|
||||
/// A 48-bit Unix timestamp.
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::base::scan::{Scan, Scanner};
|
||||
use crate::base::serial::Serial;
|
||||
use crate::base::wire::{Composer, ParseError};
|
||||
use crate::utils::base16;
|
||||
use crate::zonefile::present::{Present, ZoneFileFormatter};
|
||||
use core::cmp::Ordering;
|
||||
use core::{fmt, hash};
|
||||
use octseq::octets::{Octets, OctetsFrom, OctetsInto};
|
||||
@@ -223,6 +224,21 @@ impl<Octs: AsRef<[u8]>> fmt::Debug for Zonemd<Octs> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Octs: AsRef<[u8]>> Present for Zonemd<Octs> {
|
||||
fn present(&self, f: &mut ZoneFileFormatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
f,
|
||||
"{} {} {} ( ",
|
||||
self.serial,
|
||||
u8::from(self.scheme),
|
||||
u8::from(self.algo)
|
||||
)?;
|
||||
base16::display(&self.digest, f)?;
|
||||
write!(f, " )")
|
||||
}
|
||||
}
|
||||
|
||||
impl<Octs, Other> PartialOrd<Zonemd<Other>> for Zonemd<Octs>
|
||||
where
|
||||
Octs: AsRef<[u8]>,
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
#![cfg_attr(docsrs, doc(cfg(feature = "zonefile")))]
|
||||
|
||||
pub mod inplace;
|
||||
pub mod present;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//! Modelled roughly after `std::fmt::Display`
|
||||
|
||||
use core::fmt::{self, Write};
|
||||
use std::string::String;
|
||||
|
||||
pub struct ZoneFileFormatter<'a> {
|
||||
buf: &'a mut (dyn Write + 'a),
|
||||
}
|
||||
|
||||
pub struct Error;
|
||||
|
||||
/// Print as presentation format
|
||||
pub trait Present {
|
||||
fn present(&self, w: &mut ZoneFileFormatter) -> fmt::Result;
|
||||
|
||||
fn write_presentation<W: Write>(&self, mut w: W) -> fmt::Result {
|
||||
let mut formatter = ZoneFileFormatter {
|
||||
buf: &mut w,
|
||||
};
|
||||
self.present(&mut formatter)
|
||||
}
|
||||
|
||||
fn to_presentation_string(&self) -> String {
|
||||
let mut s = String::new();
|
||||
self.write_presentation(&mut s).unwrap();
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl ZoneFileFormatter<'_> {
|
||||
pub fn format<P: Present>(&mut self, item: &P) -> fmt::Result {
|
||||
item.present(self)
|
||||
}
|
||||
|
||||
pub fn write_bytes(&mut self, b: &[u8]) -> fmt::Result {
|
||||
for byte in b {
|
||||
self.write_char(*byte as char)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for ZoneFileFormatter<'_> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.buf.write_str(s)
|
||||
}
|
||||
|
||||
fn write_char(&mut self, c: char) -> fmt::Result {
|
||||
self.buf.write_char(c)
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
self.buf.write_fmt(args)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user