Oxidized bindings for the Nix package manager!!
Find a file
Hercules CI Effects eb056b27d9 flake.lock: Update
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/2cccadc7357c0ba201788ae99c4dfa90728ef5e0?narHash=sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q%3D' (2025-11-21)
  → 'github:hercules-ci/flake-parts/a34fae9c08a15ad73f295041fec82323541400a9?narHash=sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw%3D' (2025-12-15)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/719359f4562934ae99f5443f20aa06c2ffff91fc?narHash=sha256-b0yj6kfvO8ApcSE%2BQmA6mUfu8IYG6/uU28OFn4PaC8M%3D' (2025-10-29)
  → 'github:nix-community/nixpkgs.lib/2075416fcb47225d9b68ac469a5c4801a9c4dd85?narHash=sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo%3D' (2025-12-14)
• Updated input 'nix':
    'github:NixOS/nix/a38fc659cc4f318a45df5b61ec21745ba972f5e6?narHash=sha256-w2sPb/1UH3q5HJambT0CkdUhOxY30MHB2gPI6hStGG8%3D' (2025-12-16)
  → 'github:NixOS/nix/843395a2c87c9b0f0eb9b39bd8567c77cdabcc4e?narHash=sha256-%2BrJcHQE8yjZTR/PZpHr3eya6/Dt1DoGe/9cRoPXTI3k%3D' (2025-12-31)
• Updated input 'nix-cargo-integration':
    'github:90-008/nix-cargo-integration/f5b7a1543357cd2071cc847a9ae378328d7caa57?narHash=sha256-Rngkpanmds2XYIpFav634N2EJnmCVGlT4j04rd/XCLE%3D' (2025-12-13)
  → 'github:90-008/nix-cargo-integration/525ccaf24a3e3b5d28a4dbec8a9c4e1ca759db8e?narHash=sha256-5hrqsS9pnPl1ptnJVtEUkUcbr9feYH8OG14pKRnbG2U%3D' (2025-12-31)
• Updated input 'nix-cargo-integration/dream2nix':
    'github:nix-community/dream2nix/343053a4dfa53ce8abfc35e918cd4ab990abc58d?narHash=sha256-nZjNYEvNKZRF0%2BkoTN2azGWbGlsvLNUTF6PcC0eqTa4%3D' (2025-12-11)
  → 'github:nix-community/dream2nix/69eb01fa0995e1e90add49d8ca5bcba213b0416f?narHash=sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI%3D' (2025-12-17)
• Updated input 'nix-cargo-integration/parts':
    'github:hercules-ci/flake-parts/5635c32d666a59ec9a55cab87e898889869f7b71?narHash=sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM%3D' (2025-12-11)
  → 'github:hercules-ci/flake-parts/a34fae9c08a15ad73f295041fec82323541400a9?narHash=sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw%3D' (2025-12-15)
• Updated input 'nix-cargo-integration/rust-overlay':
    'github:oxalica/rust-overlay/348b94ed9ddffccdf1a65582a2dcff0a4a3eeeb4?narHash=sha256-qbl874bCIy9%2BOLImdfBfZ9ITUDDjjTAB04Dk4PlZFV0%3D' (2025-12-13)
  → 'github:oxalica/rust-overlay/6d14586a5917a1ec7f045ac97e6d00c68ea5d9f3?narHash=sha256-TjfAb58Ybz/93e2jP0qD846dj%2BVqiY7wk%2BEqsxcZ708%3D' (2025-12-31)
• Updated input 'nix-cargo-integration/treefmt':
    'github:numtide/treefmt-nix/5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4?narHash=sha256-AlEObg0syDl%2BSpi4LsZIBrjw%2BsnSVU4T8MOeuZJUJjM%3D' (2025-11-12)
  → 'github:numtide/treefmt-nix/dec15f37015ac2e774c84d0952d57fcdf169b54d?narHash=sha256-yOt/FTB7oSEKQH9EZMFMeuldK1HGpQs2eAzdS9hNS/o%3D' (2025-12-30)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/addf7cf5f383a3101ecfba091b98d0a1263dc9b8?narHash=sha256-hM20uyap1a0M9d344I692r%2Bik4gTMyj60cQWO%2BhAYP8%3D' (2025-12-08)
  → 'github:NixOS/nixpkgs/c0b0e0fddf73fd517c3471e546c0df87a42d53f4?narHash=sha256-coBu0ONtFzlwwVBzmjacUQwj3G%2BlybcZ1oeNSQkgC0M%3D' (2025-12-28)
2026-01-01 02:32:56 +00:00
.vscode dev: Recommend against clangd vscode extension 2025-10-04 02:31:17 +02:00
dev dev: Adjust shell 2025-12-09 23:02:42 +01:00
doc/hacking maint: Move to /rust/* to / 2025-10-26 23:29:13 +01:00
nix-bindings-bindgen-raw maint: Move to /rust/* to / 2025-10-26 23:29:13 +01:00
nix-bindings-expr Dereference workspace lints for nix-cargo-integration compatibility 2025-12-16 03:06:58 +01:00
nix-bindings-fetchers Dereference workspace lints for nix-cargo-integration compatibility 2025-12-16 03:06:58 +01:00
nix-bindings-flake Dereference workspace lints for nix-cargo-integration compatibility 2025-12-16 03:06:58 +01:00
nix-bindings-store Dereference workspace lints for nix-cargo-integration compatibility 2025-12-16 03:06:58 +01:00
nix-bindings-util Dereference workspace lints for nix-cargo-integration compatibility 2025-12-16 03:06:58 +01:00
.envrc feat: Rust skeleton 2025-09-30 17:57:50 +02:00
.gitignore feat: Rust skeleton 2025-09-30 17:57:50 +02:00
bindgen-gcc.sh maint: Move to /rust/* to / 2025-10-26 23:29:13 +01:00
Cargo.lock maint: Move to /rust/* to / 2025-10-26 23:29:13 +01:00
Cargo.toml Fix clippy and track in CI 2025-12-15 19:48:45 -05:00
flake.lock flake.lock: Update 2026-01-01 02:32:56 +00:00
flake.nix Exclude clippy checks from flake module for dependents 2025-12-28 18:19:58 +01:00
LICENSE License as LGPL-2.1 2025-10-04 02:31:16 +02:00
nci.nix Format, and keep formatted 2025-12-05 16:55:09 -05:00
README.md doc: Update README 2025-12-16 01:48:56 +01:00

Nix Bindings for Rust

Rust bindings for the Nix C API, providing safe, idiomatic Rust interfaces to Nix's core functionality including store operations, expression evaluation, and flake management.

Overview

This workspace provides multiple crates that wrap different layers of the Nix C API:

  • nix-bindings-util - Utility types and helpers (settings, context, version detection, string handling)
  • nix-bindings-store - Store operations (paths, derivations, store management)
  • nix-bindings-expr - Expression evaluation and type extraction
  • nix-bindings-flake - Flake operations
  • nix-bindings-fetchers - Fetcher functionality (requires Nix ≥ 2.29)

The nix-bindings-bindgen-raw crate contains the generated FFI bindings and is not intended for direct use.

Features

  • Nix evaluation - Evaluate Nix expressions and create and extract values
  • Store integration - Interact with the Nix store, manage paths, build derivations
  • Threading - GC registration and memory management via Drop
  • Lazy evaluation - Fine-grained control over evaluation strictness
  • Version compatibility - Conditional compilation for different Nix versions

Quick Start

Add the crates you need to your Cargo.toml:

[dependencies]
nix-bindings-store = { git = "https://github.com/nixops4/nix-bindings-rust" }
nix-bindings-expr = { git = "https://github.com/nixops4/nix-bindings-rust" }

Basic example:

use nix_bindings_expr::eval_state::{EvalState, init, gc_register_my_thread};
use nix_bindings_store::store::Store;
use std::collections::HashMap;

fn main() -> anyhow::Result<()> {
    // Initialize Nix library and register thread with GC
    init()?;
    let guard = gc_register_my_thread()?;

    // Open a store connection and create an evaluation state
    let store = Store::open(None, HashMap::new())?;
    let mut eval_state = EvalState::new(store, [])?;

    // Evaluate a Nix expression
    let value = eval_state.eval_from_string("[1 2 3]", "<example>")?;

    // Extract typed values
    let elements: Vec<_> = eval_state.require_list_strict(&value)?;
    for element in elements {
        let num = eval_state.require_int(&element)?;
        println!("Element: {}", num);
    }

    drop(guard);
    Ok(())
}

Usage Examples

Evaluating Nix Expressions

use nix_bindings_expr::eval_state::EvalState;

// Evaluate and extract different types
let int_value = eval_state.eval_from_string("42", "<example>")?;
let num = eval_state.require_int(&int_value)?;

let str_value = eval_state.eval_from_string("\"hello\"", "<example>")?;
let text = eval_state.require_string(&str_value)?;

let attr_value = eval_state.eval_from_string("{ x = 1; y = 2; }", "<example>")?;
let attrs = eval_state.require_attrs(&attr_value)?;

Working with Lists

let list_value = eval_state.eval_from_string("[1 2 3 4 5]", "<example>")?;

// Lazy: check size without evaluating elements
let size = eval_state.require_list_size(&list_value)?;

// Selective: evaluate only accessed elements
if let Some(first) = eval_state.require_list_select_idx_strict(&list_value, 0)? {
    let value = eval_state.require_int(&first)?;
}

// Strict: evaluate all elements
let all_elements: Vec<_> = eval_state.require_list_strict(&list_value)?;

Thread Safety

Before using EvalState in a thread, register with the garbage collector:

use nix_bindings_expr::eval_state::{init, gc_register_my_thread};

init()?;  // Once per process
let guard = gc_register_my_thread()?;  // Once per thread
// ... use EvalState ...
drop(guard);  // Unregister when done

For more examples, see the documentation in each crate's source code.

Nix Version Compatibility

The crates use conditional compilation to support multiple Nix versions:

  • nix-bindings-fetchers requires Nix ≥ 2.29
  • Some features in other crates require specific Nix versions

The build system automatically detects the Nix version and enables appropriate features.

Integration with Nix Projects

These crates use nix-cargo-integration for seamless integration with Nix builds. To use them in your Nix project:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-parts.url = "github:hercules-ci/flake-parts";
    nix-cargo-integration.url = "github:90-008/nix-cargo-integration";
    nix-bindings-rust.url = "github:nixops4/nix-bindings-rust";
  };

  outputs = inputs@{ flake-parts, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      imports = [
        inputs.nix-cargo-integration.flakeModule
        inputs.nix-bindings-rust.modules.flake.default
      ];

      perSystem = { config, pkgs, ... }: {
        # Optional: override Nix package
        nix-bindings-rust.nixPackage = pkgs.nix;

        nci.projects."myproject" = {
          depsDrvConfig = {
            imports = [ config.nix-bindings-rust.nciBuildConfig ];
          };
        };
      };
    };
}

See the nix-cargo-integration documentation for more options.

Development

Getting Started

$ nix develop

Building

# Build specific crates (release mode)
nix build .#nix-bindings-store-release
nix build .#nix-bindings-expr-release

# Build with Cargo (in dev shell)
cargo build
cargo build --release

Testing

# Run tests for specific crates via Nix (recommended - includes proper store setup)
nix build .#checks.x86_64-linux.nix-bindings-store-tests
nix build .#checks.x86_64-linux.nix-bindings-expr-tests

# Run all checks (tests + clippy + formatting)
nix flake check

# Run tests with Cargo (in dev shell)
cargo test

# Run specific test
cargo test test_name

Memory Testing

For FFI memory leak testing with valgrind, see doc/hacking/test-ffi.md.

Code Formatting

treefmt

IDE Setup

For VSCode, load the dev shell via Nix Env Selector extension or direnv.

Documentation

License

See LICENSE file in the repository.