You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: dns.rs
    path of file: ./repos/realm/src/conf
    
    the code of the file until where you have to start completion: use std::fmt::{Formatter, Display};
use std::net::ToSocketAddrs;

use serde::{Serialize, Deserialize};
use realm_core::dns::config;
use config::{LookupIpStrategy, NameServerConfig, Protocol};
use config::{ResolverConfig, ResolverOpts};

use super::Config;

// dns mode
#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum DnsMode {
    Ipv4Only,
    Ipv6Only,
    #[default]
    Ipv4AndIpv6,
    Ipv4ThenIpv6,
    Ipv6ThenIpv4,
}

impl Display for DnsMode {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        use DnsMode::*;
        let s = match self {
            Ipv4Only => "ipv4_only",
            Ipv6Only => "ipv6_only",
            Ipv4AndIpv6 => "ipv4_and_ipv6",
            Ipv4ThenIpv6 => "ipv4_then_ipv6",
            Ipv6ThenIpv4 => "ipv6_then_ipv4",
        };
        write!(f, "{}", s)
    }
}

impl From<String> for DnsMode {
    fn from(s: String) -> Self {
        use DnsMode::*;
        match s.to_ascii_lowercase().as_str() {
            "ipv4_only" => Ipv4Only,
            "ipv6_only" => Ipv6Only,
            "ipv4_and_ipv6" => Ipv4AndIpv6,
            "ipv4_then_ipv6" => Ipv4ThenIpv6,
            "ipv6_then_ipv4" => Ipv6ThenIpv4,
            _ => Self::default(),
        }
    }
}

impl From<DnsMode> for LookupIpStrategy {
    fn from(mode: DnsMode) -> Self {
        match mode {
            DnsMode::Ipv4Only => LookupIpStrategy::Ipv4Only,
            DnsMode::Ipv6Only => LookupIpStrategy::Ipv6Only,
            DnsMode::Ipv4AndIpv6 => LookupIpStrategy::Ipv4AndIpv6,
            DnsMode::Ipv4ThenIpv6 => LookupIpStrategy::Ipv4thenIpv6,
            DnsMode::Ipv6ThenIpv4 => LookupIpStrategy::Ipv6thenIpv4,
        }
    }
}

// dns protocol
#[derive(Debug, Default, Serialize, Deserialize, Eq, PartialEq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum DnsProtocol {
    Tcp,
    Udp,
    #[default]
    TcpAndUdp,
}

impl Display for DnsProtocol {
    fn fmt(&self, f: &mut For
    
    fn build(self) -> Self::Output {
        use crate::empty;
        use std::time::Duration;

        let DnsConf {
            mode,
            protocol,
            nameservers,
            min_ttl,
            max_ttl,
            cache_size,
        } = self;

        // parse into ResolverOpts
        // default value:
        // https://docs.rs/trust-dns-resolver/latest/src/trust_dns_resolver/config.rs.html#681-737

        let opts = if empty![mode, min_ttl, max_ttl, cache_size] {
            None
        } else {
            let ip_strategy: LookupIpStrategy = mode.map(|x| x.into()).unwrap_or_default();

            let positive_min_ttl = min_ttl.map(|x| Duration::from_secs(x as u64));

            let positive_max_ttl = max_ttl.map(|x| Duration::from_secs(x as u64));

            let cache_size = cache_size.unwrap_or({
                let ResolverOpts { cache_size, .. } = Default::default();
                cache_size
            });

            let mut opts = ResolverOpts::default();

            macro_rules! replace {
                ($($x: ident, )+) => {
                    $(
                        opts.$x = $x;
                    )+
                }
            }

            replace!(ip_strategy, positive_min_ttl, positive_max_ttl, cache_size,);

            Some(opts)
        };

        // parse into ResolverConfig
        let protocol = protocol.unwrap_or_default();
        if nameservers.is_none() && (protocol == DnsProtocol::default()) {
            return (None, opts);
        }

        let mut conf = ResolverConfig::new();
        let protocols: Vec<Protocol> = protocol.into();
        let nameservers = match nameservers {
            Some(addrs) => addrs
                .iter()
                .map(|x| x.to_socket_addrs().unwrap().next().unwrap())
                .collect(),
            None => {
                use realm_core::dns::DnsConf as TrustDnsConf;
                let TrustDnsConf { conf, .. } = TrustDnsConf::default();
                let mut addrs: Vec<std::net::SocketAddr> = conf.name_servers().iter().map(|x| x.socket_addr).collect();
                addrs.dedup();
                addrs
            }
        };

        for socket_addr in nameservers {
            for protocol in protocols.clone() {
                conf.add_name_server(NameServerConfig {
                    socket_addr,
                    protocol,
                    tls_dns_name: None,
                    trust_negative_responses: true,
                    bind_addr: None,
                });
            }
        }

        (Some(conf), opts)
    }