ztoh/
main.rs

1use clap::Parser;
2use std::io::{stdin, Read};
3use std::process;
4
5use dns_types::hosts::types::Hosts;
6use dns_types::zones::types::Zone;
7
8// the doc comments for this struct turn into the CLI help text
9#[derive(Parser)]
10/// Read a zone file from stdin, convert it to a hosts file, and
11/// output it in a normalised form to stdout.
12///
13/// Hosts files can only contain non-wildcard A and AAAA records, so
14/// this conversion is lossy.
15///
16/// Part of resolved.
17struct Args {
18    /// Return an error if the zone file contains any records which
19    /// cannot be represented in a hosts file.
20    #[clap(long, action(clap::ArgAction::SetTrue))]
21    strict: bool,
22}
23
24fn main() {
25    let args = Args::parse();
26
27    let mut buf = String::new();
28    if let Err(err) = stdin().read_to_string(&mut buf) {
29        eprintln!("error reading zone file from stdin: {err:?}");
30        process::exit(1);
31    }
32
33    match Zone::deserialise(&buf) {
34        Ok(zone) => {
35            let try_hosts = if args.strict {
36                Hosts::try_from(zone)
37            } else {
38                Ok(Hosts::from_zone_lossy(&zone))
39            };
40            match try_hosts {
41                Ok(hosts) => print!("{}", hosts.serialise()),
42                Err(err) => {
43                    eprintln!("error converting zone file to hosts file: {err:?}");
44                    process::exit(1);
45                }
46            }
47        }
48        Err(err) => {
49            eprintln!("error parsing zone file from stdin: {err:?}");
50            process::exit(1);
51        }
52    }
53}