Read/write Guix Scheme files from Rust
  • Rust 99.7%
  • Scheme 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-08 07:58:43 +01:00
.github/workflows feat: initial release 2026-07-07 20:53:26 +01:00
guix-scheme feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
scheme-edit feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
.envrc feat: initial release 2026-07-07 20:53:26 +01:00
.gitignore feat: initial release 2026-07-07 20:53:26 +01:00
Cargo.toml feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
CHANGELOG.md feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
LICENSE-APACHE feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
LICENSE-MIT feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00
manifest.scm feat: initial release 2026-07-07 20:53:26 +01:00
README.md feat: fallible OsBuilder, operating-system view, and parity/validation tests 2026-07-08 07:58:43 +01:00

guix-scheme

CI

Read/write Guix Scheme files from Rust: parse and edit channels.scm without losing comments or formatting, and generate operating-system configurations. Built on a lossless S-expression concrete syntax tree, so untouched parts of a file survive edits byte-for-byte.

Crate Purpose
guix-scheme Typed views over Guix files: channels read/add/remove, operating-system builder, record field access Crates.io Docs.rs
scheme-edit Generic lossless Scheme CST parser and editor (toml_edit-style), no Guix specifics Crates.io Docs.rs

Editing channels.scm

use guix_scheme::{Channel, ChannelsFile};

let src = std::fs::read_to_string("channels.scm")?;
let mut cf = ChannelsFile::parse(&src)?;

cf.add_channel(&Channel {
    name: "pantherx".into(),
    url: "https://codeberg.org/gofranz/panther.git".into(),
    branch: Some("master".into()),
    commit: None,
    introduction_commit: Some("54b4056ac571611892c743b65f4c47dc298c49da".into()),
    introduction_fingerprint: Some("A36A D41E ECC7 A871 1003  5D24 524F EB1A 9D33 C9CB".into()),
})?;

cf.remove_channel("nonguix")?;
std::fs::write("channels.scm", cf.to_string())?;

Comments, indentation, and everything you didn't touch come back byte-identical.

A note on what this is (and isn't)

Parsing Guix Scheme from Rust is not ideal, and this crate cannot validate content. It's a poor man's workaround for when Guix isn't available, or when you'd rather read and write these files from Rust. Scheme and Guix are a full language and application; guix-scheme is just a dumb parser. It won't tell you if something is missing (a module import, a required field) or otherwise wrong. If you need real validation, feed the result through Guix itself (see the guile-check feature below for a partial check).

Generating an operating-system

use guix_scheme::os_builder::{FsDevice, OsBuilder, OsFlavor};

let config = OsBuilder::new(OsFlavor::Guix, "my-box", "Europe/Berlin", "en_US.utf8")
    .bootloader_efi("/boot/efi")
    .file_system("/", FsDevice::Label("root".into()), "ext4", false)
    .user("franz", "Franz", &["wheel", "netdev", "audio", "video"])
    .services_field("%desktop-services")
    .build();

Feature flags

  • guile-check (guix-scheme): validate generated/edited source by feeding it through a real guile reader. Off by default; requires guile on PATH at runtime.

MSRV

Rust 1.70 (2021 edition). Verified to build on 1.70; also tested on current stable.

Fixture sources

The test corpus (35 files under scheme-edit/tests/fixtures/) is copied verbatim from GNU Guix, libguix, guix-install, and community configuration repos found via awesome-guix. Each file keeps its original copyright and license. Full credits: scheme-edit/tests/fixtures/SOURCES.md.

License

Licensed under either of MIT or Apache-2.0 at your option.