use core::cmp::Ordering;
use super::wire::{BuildBytes, TruncationError};
mod label;
pub use label::{Label, LabelBuf, LabelIter, LabelParseError};
mod absolute;
pub use absolute::{Name, NameBuf, NameParseError};
mod reversed;
pub use reversed::{RevName, RevNameBuf};
mod unparsed;
pub use unparsed::UnparsedName;
mod compressor;
pub use compressor::NameCompressor;
pub trait CanonicalName: BuildBytes + Ord {
fn build_lowercased_bytes<'b>(
&self,
bytes: &'b mut [u8],
) -> Result<&'b mut [u8], TruncationError> {
let rest = self.build_bytes(bytes)?.len();
let (bytes, rest) = bytes.split_at_mut(rest);
bytes.make_ascii_lowercase();
Ok(rest)
}
fn cmp_composed(&self, other: &Self) -> Ordering {
let mut this = [0u8; 255];
let rest_len = self
.build_bytes(&mut this)
.expect("domain names are at most 255 bytes when serialized")
.len();
let this = &this[..this.len() - rest_len];
let mut that = [0u8; 255];
let rest_len = other
.build_bytes(&mut that)
.expect("domain names are at most 255 bytes when serialized")
.len();
let that = &that[..that.len() - rest_len];
this.cmp(that)
}
fn cmp_lowercase_composed(&self, other: &Self) -> Ordering {
let mut this = [0u8; 255];
let rest_len = self
.build_lowercased_bytes(&mut this)
.expect("domain names are at most 255 bytes when serialized")
.len();
let this = &this[..this.len() - rest_len];
let mut that = [0u8; 255];
let rest_len = other
.build_lowercased_bytes(&mut that)
.expect("domain names are at most 255 bytes when serialized")
.len();
let that = &that[..that.len() - rest_len];
this.cmp(that)
}
}
macro_rules! impl_canonical_name_for_deref {
{$(
$(#[$attr:meta])*
impl[$($args:tt)*] CanonicalName for $subject:ty;
)*} => {$(
$(#[$attr])*
impl<$($args)*> CanonicalName for $subject {
fn build_lowercased_bytes<'b>(
&self,
bytes: &'b mut [u8],
) -> Result<&'b mut [u8], TruncationError> {
(**self).build_lowercased_bytes(bytes)
}
fn cmp_composed(&self, other: &Self) -> Ordering {
(**self).cmp_composed(&**other)
}
fn cmp_lowercase_composed(&self, other: &Self) -> Ordering {
(**self).cmp_lowercase_composed(&**other)
}
}
)*};
}
impl_canonical_name_for_deref! {
impl[N: ?Sized + CanonicalName] CanonicalName for &N;
impl[N: ?Sized + CanonicalName] CanonicalName for &mut N;
#[cfg(feature = "alloc")]
impl[N: ?Sized + CanonicalName] CanonicalName for alloc::boxed::Box<N>;
#[cfg(feature = "alloc")]
impl[N: ?Sized + CanonicalName] CanonicalName for alloc::rc::Rc<N>;
#[cfg(feature = "alloc")]
impl[N: ?Sized + CanonicalName] CanonicalName for alloc::sync::Arc<N>;
}