rust-dnsbox/lib/dnsbox-base/src/common_types/name/display.rs

80 lines
1.9 KiB
Rust

use std::fmt;
use super::DnsLabelRef;
/// Customize formatting of DNS labels
///
/// The default uses "." as separator and adds a trailing separator.
///
/// The `Debug` formatters just format as `Display` to a String and then
/// format that string as `Debug`.
#[derive(Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash,Debug)]
pub struct DisplayLabelsOptions {
/// separator to insert between (escaped) labels
pub separator: &'static str,
/// whether a trailing separator is added.
///
/// without a trailing separator the root zone is represented as
/// empty string!
pub trailing: bool,
}
impl Default for DisplayLabelsOptions {
fn default() -> Self {
DisplayLabelsOptions{
separator: ".",
trailing: true,
}
}
}
/// Wrap anything representing a collection of labels (`DnsLabelRef`) to
/// format using the given `options`.
///
/// As name you can pass any cloneable `(Into)Iterator` with
/// `DnsLabelRef` items, e.g:
///
/// * `&DnsName`
/// * `DnsNameIterator`
#[derive(Clone)]
pub struct DisplayLabels<'a, I>
where
I: IntoIterator<Item=DnsLabelRef<'a>>+Clone
{
/// Label collection to iterate over
pub labels: I,
/// Options
pub options: DisplayLabelsOptions,
}
impl<'a, I> fmt::Debug for DisplayLabels<'a, I>
where
I: IntoIterator<Item=DnsLabelRef<'a>>+Clone
{
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
// just escape the display version1
format!("{}", self).fmt(w)
}
}
impl<'a, I> fmt::Display for DisplayLabels<'a, I>
where
I: IntoIterator<Item=DnsLabelRef<'a>>+Clone
{
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
let mut i = self.labels.clone().into_iter();
if let Some(first_label) = i.next() {
// first label
fmt::Display::fmt(&first_label, w)?;
// remaining labels
while let Some(label) = i.next() {
w.write_str(self.options.separator)?;
fmt::Display::fmt(&label, w)?;
}
}
if self.options.trailing {
w.write_str(self.options.separator)?;
}
Ok(())
}
}