dns-update-lite 0.5.9

Dynamic DNS update (RFC 2136 and cloud) library for Rust. Lightweight fork of dns-update
Documentation
use crate::{DnsRecord, IntoFqdn, NamedDnsRecord};

pub struct BindSerializer;

impl BindSerializer {
    pub fn serialize(records: &[NamedDnsRecord]) -> String {
        let mut output = String::new();
        for named in records {
            let name = &named.name;
            match &named.record {
                DnsRecord::A(addr) => {
                    output.push_str(&format!("{name} IN A {addr}\n"));
                }
                DnsRecord::AAAA(addr) => {
                    output.push_str(&format!("{name} IN AAAA {addr}\n"));
                }
                DnsRecord::CNAME(cname) => {
                    output.push_str(&format!("{name} IN CNAME {}\n", cname.into_fqdn()));
                }
                DnsRecord::NS(ns) => {
                    output.push_str(&format!("{name} IN NS {}\n", ns.into_fqdn()));
                }
                DnsRecord::MX(mx) => {
                    output.push_str(&format!(
                        "{name} IN MX {} {}\n",
                        mx.priority,
                        (&mx.exchange).into_fqdn()
                    ));
                }
                DnsRecord::TXT(text) => {
                    output.push_str(&format!("{name} IN TXT "));
                    if text.len() <= 255 {
                        output.push_str(&format!("\"{}\"\n", escape_txt(text)));
                    } else {
                        output.push_str("(\n");
                        for chunk in text.as_bytes().chunks(255) {
                            let chunk_str = String::from_utf8_lossy(chunk);
                            output.push_str(&format!("    \"{}\"\n", escape_txt(&chunk_str)));
                        }
                        output.push_str(")\n");
                    }
                }
                DnsRecord::SRV(srv) => {
                    output.push_str(&format!(
                        "{name} IN SRV {} {} {} {}\n",
                        srv.priority,
                        srv.weight,
                        srv.port,
                        (&srv.target).into_fqdn()
                    ));
                }
                DnsRecord::TLSA(tlsa) => {
                    output.push_str(&format!("{name} IN TLSA {tlsa}\n"));
                }
                DnsRecord::CAA(caa) => {
                    output.push_str(&format!("{name} IN CAA {caa}\n"));
                }
                DnsRecord::HTTPS(https) => {
                    output.push_str(&format!("{name} IN HTTPS {https}\n"));
                }
            }
        }
        output
    }
}

#[inline(always)]
fn escape_txt(s: &str) -> String {
    s.replace('\\', "\\\\").replace('"', "\\\"")
}