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>+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>+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>+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(()) } }