mhost 0.11.3

Fast, async DNS lookup library and CLI -- modern dig/host replacement with parallel multi-server queries, DoH, DoT, subdomain discovery, and zone verification
Documentation
// Copyright 2017-2021 Lukas Pustina <lukas@pustina.de>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::collections::HashSet;

use crate::Error;

#[derive(Debug)]
pub struct SummaryOptions {
    /// Show numbers, times, and dates in human readable form
    human: bool,
    /// Reduce output to an as concise as possible form
    condensed: bool,
    /// Show domain names queried
    show_domain_names: bool,
}

impl SummaryOptions {
    pub fn new(human: bool, condensed: bool, show_domain_names: bool) -> SummaryOptions {
        SummaryOptions {
            human,
            condensed,
            show_domain_names,
        }
    }

    pub fn human(&self) -> bool {
        self.human
    }

    pub fn condensed(&self) -> bool {
        self.condensed
    }

    pub fn show_domain_names(&self) -> bool {
        self.show_domain_names
    }
}

impl Default for SummaryOptions {
    fn default() -> Self {
        SummaryOptions {
            human: true,
            condensed: false,
            show_domain_names: false,
        }
    }
}

static VALID_SUMMARY_OPTIONS: &[&str] = &["human", "condensed", "show-domain-names"];

impl<'a> TryFrom<Vec<&'a str>> for SummaryOptions {
    type Error = Error;

    fn try_from(values: Vec<&'a str>) -> std::result::Result<Self, Self::Error> {
        let options: HashSet<&str> = values.into_iter().collect();
        for opt in &options {
            if !VALID_SUMMARY_OPTIONS.contains(opt) {
                return Err(Error::ParserError {
                    what: opt.to_string(),
                    to: "SummaryOptions",
                    why: format!(
                        "unknown option '{}', valid options are: {}",
                        opt,
                        VALID_SUMMARY_OPTIONS.join(", ")
                    ),
                });
            }
        }
        Ok(SummaryOptions {
            human: options.contains("human"),
            condensed: options.contains("condensed"),
            show_domain_names: options.contains("show-domain-names"),
        })
    }
}

pub trait Rendering {
    fn render(&self, opts: &SummaryOptions) -> String;

    #[allow(unused_variables)]
    fn render_with_suffix(&self, suffix: &str, opts: &SummaryOptions) -> String {
        self.render(opts)
    }
}