guix-scheme 0.1.0

Read, edit, and generate Guix Scheme files (channels.scm, system config.scm) from Rust
Documentation
//! Typed reads over real guix package and service modules.

use guix_scheme::record::RecordView;
use scheme_edit::Document;
use std::path::Path;

fn fx(dir: &str, name: &str) -> String {
    let p = Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("../scheme-edit/tests/fixtures")
        .join(dir)
        .join(name);
    std::fs::read_to_string(p).unwrap()
}

#[test]
fn cpio_module_forms_and_package_record() {
    let src = fx("packages", "cpio.scm");
    let doc = Document::parse(&src).unwrap();
    assert_eq!(doc.to_string(), src, "round-trip must be byte-identical");

    let heads: Vec<&str> = doc.forms().filter_map(|n| n.head_symbol()).collect();
    assert!(heads.contains(&"define-module"));
    assert!(heads.contains(&"define-public"));

    let dp = doc
        .forms()
        .find(|n| {
            n.head_symbol() == Some("define-public") && n.to_source().contains("(name \"cpio\")")
        })
        .unwrap();
    let pkg = dp
        .list_nodes()
        .find(|n| n.head_symbol() == Some("package"))
        .unwrap();
    let v = RecordView::new(pkg).unwrap();
    assert_eq!(v.record_name(), "package");
    assert_eq!(v.string_field("name").as_deref(), Some("cpio"));
    assert!(v.string_field("version").is_some_and(|s| !s.is_empty()));
}

#[test]
fn avahi_module_has_record_type_definition() {
    let src = fx("services", "avahi.scm");
    let doc = Document::parse(&src).unwrap();
    assert_eq!(doc.to_string(), src, "round-trip must be byte-identical");

    assert!(doc
        .forms()
        .any(|n| n.head_symbol() == Some("define-record-type*")));
    assert!(doc.forms().count() > 5);
}