Writing & Formatting¶
Hornet can serialise any parsed AST back to valid BIND9 text. The output is controlled by
WriteOptions, which supports configurable indentation, keyword style, and statement spacing.
WriteOptions¶
use hornet_bind9::writer::WriteOptions;
let opts = WriteOptions {
indent: 4, // spaces per indent level
modern_keywords: true, // master → primary, slave → secondary
explicit_class: false, // always emit "IN" class on zone/view
blank_between_statements: true, // blank line between top-level statements
};
All fields have sensible defaults:
let opts = WriteOptions::default();
// indent: 4
// modern_keywords: true
// explicit_class: false
// blank_between_statements: true
Writing named.conf¶
use hornet_bind9::{parse_named_conf, write_named_conf};
use hornet_bind9::writer::WriteOptions;
let conf = parse_named_conf(input)?;
// Default formatting
let output = write_named_conf(&conf, &WriteOptions::default());
println!("{output}");
Compact formatting¶
let opts = WriteOptions {
indent: 2,
blank_between_statements: false,
..Default::default()
};
let compact = write_named_conf(&conf, &opts);
Legacy keyword preservation¶
let opts = WriteOptions {
modern_keywords: false, // keep master/slave as-is
..Default::default()
};
let legacy = write_named_conf(&conf, &opts);
Writing zone files¶
use hornet_bind9::{parse_zone_file, write_zone_file};
use hornet_bind9::writer::WriteOptions;
let zone = parse_zone_file(zone_text)?;
let output = write_zone_file(&zone, &WriteOptions::default());
println!("{output}");
Round-trip fidelity¶
Hornet is designed for round-trip fidelity: parsing a file and writing it back with default options produces semantically equivalent output. Whitespace and comment formatting may differ, but all structured data is preserved.
let conf_a = parse_named_conf(input)?;
let text_b = write_named_conf(&conf_a, &WriteOptions::default());
let conf_b = parse_named_conf(&text_b)?;
// conf_a and conf_b are semantically equivalent
assert_eq!(conf_a.statements.len(), conf_b.statements.len());
In-place formatting¶
To reformat a file on disk:
use std::path::Path;
use hornet_bind9::{parse_named_conf_file, write_named_conf};
use hornet_bind9::writer::WriteOptions;
fn fmt_file(path: &Path) -> hornet::Result<()> {
let conf = parse_named_conf_file(path)?;
let formatted = write_named_conf(&conf, &WriteOptions::default());
std::fs::write(path, &formatted)?;
Ok(())
}
Tip
Use the CLI's hornet fmt command for in-place formatting without writing Rust code.
See fmt.
Check-only mode¶
To verify formatting without writing:
let original = std::fs::read_to_string(path)?;
let conf = parse_named_conf_file(path)?;
let formatted = write_named_conf(&conf, &WriteOptions::default());
if formatted != original {
eprintln!("File would be reformatted: {}", path.display());
std::process::exit(1);
}
Next Steps¶
- Validating — Check configs for semantic errors before writing
- WriteOptions Reference — Full field documentation
- fmt CLI — In-place formatting via the CLI
- convert CLI — Keyword migration via the CLI