CROW crow-config.errorware.net
v0.1.0-engine · 23/23 tests pass · 0 panics
git@github.com:errorware/crow-config-docs.git
CORE ENGINE · SYSTEM REFERENCE

crow-config

crow-config is a standalone, panic-free Rust engine that transforms arbitrary line- and block-oriented Linux configuration files (/etc/hosts, sshd_config, pg_hba.conf, ufw.rules) into structured, typed, round-trippable intermediate representations (IR).

Zero UI dependencies. Zero filesystem side effects. Pure in-memory transformation. Designed specifically for mission-critical server control panels where corrupted configuration writes cannot be tolerated.

Core Guarantees

  • 100% LOSSLESS CST Every comment, indentation tab, space, and blank line is preserved. Serialization of an unedited document outputs the original bytes identically.
  • SURGICAL EDITS Modifying a field or IP address mutates only the targeted token in the Concrete Syntax Tree. Surrounding comments and alignment tabs remain untouched.
  • PANIC-FREE RESILIENCE Malformed syntax or unexpected tokens are safely captured in Error nodes without crashing the process.
  • RISK RATINGS Declarative TOML manifests categorize values into security risk tiers (recommended, caution, weak, never_on_prod).
  • VIEW-BINDING IR Emits generic widget kinds (rule_table, key_value_list) so UI components render and mutate files without format-specific code.

Quick Rust Example

use crow_config_core::edit::{ConfigDocument, EditOp};
use crow_config_schemas::HostsPlugin;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let hosts = "127.0.0.1  localhost\n10.0.4.12  db-01  # primary postgres\n";
    let plugin = HostsPlugin::new();

    // 1. Parse into an in-memory document
    let mut doc = ConfigDocument::parse(&plugin, hosts)?;

    // 2. Generate generic View-Binding IR for the UI
    let ir = doc.to_ir()?;

    // 3. Apply an in-place semantic edit
    doc.apply_edit(&EditOp::UpdateField {
        row_id: "line-2".to_string(),
        field_name: "address".to_string(),
        new_value: serde_json::json!("10.0.4.13"),
    })?;

    // 4. Serialize back — only the modified IP token changed!
    let updated = doc.serialize();
    assert_eq!(updated, "127.0.0.1  localhost\n10.0.4.13  db-01  # primary postgres\n");

    Ok(())
}