80 lines
1.9 KiB
Rust
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(())
|
||
|
}
|
||
|
}
|