Expand description
§Nix Expression Evaluation
This module provides the core EvalState type for evaluating Nix expressions
and extracting typed values from the results.
§Overview
The EvalState manages the evaluation context for Nix expressions, including:
- Expression parsing and evaluation with
eval_from_string - Type-safe value extraction with
require_*methods - Memory management and garbage collection integration
- Store integration for derivations and store paths
- Custom function creation with
new_value_primopandnew_value_thunk
§Construction
Create an EvalState using EvalState::new or EvalStateBuilder for advanced configuration:
let store = Store::open(None, HashMap::new())?;
// Simple creation
let mut es = EvalState::new(store.clone(), [])?;
// With custom lookup paths
let mut es = EvalStateBuilder::new(store)?
.lookup_path(["nixpkgs=/path/to/nixpkgs"])?
.build()?;§Value Extraction
All require_* methods perform these steps:
- Evaluation: Force evaluation of thunks as needed
- Type checking: Verify the value matches the expected type
- Extraction: Return the typed Rust value or an error
Methods with _strict in their name also evaluate their return values before returning them.
§Evaluation Strictness
- Lazy methods (e.g.,
require_list_size): Evaluate only the structure needed - Strict methods (e.g.,
require_list_strict): Force full evaluation of all contained values - Selective methods (e.g.,
require_list_select_idx_strict): Evaluate only the accessed elements
§Laziness and Strictness
The terms “lazy” and “strict” in this API refer to Nix’s Weak Head Normal Form (WHNF)
evaluation model, not the kind of deep strictness that is exercised by functions such as builtins.toJSON or builtins.deepSeq.
- WHNF evaluation: Values are evaluated just enough to determine their type and basic structure
- Deep evaluation: All nested values are recursively forced (like
builtins.deepSeq)
For example, a list in WHNF has its length determined but individual elements may remain unevaluated thunks. Methods marked as “strict” in this API force WHNF evaluation of their results, but do not perform deep evaluation of arbitrarily nested structures unless explicitly documented otherwise.
§Thread Safety and Memory Management
Before using EvalState in a thread, register it with the (process memory) garbage collector:
init()?; // Initialize Nix library
let guard = gc_register_my_thread()?; // Register thread with GC
// Now safe to use EvalState in this thread
drop(guard);§Error Handling
Evaluation methods return Result types. Common error scenarios include:
- Type mismatches: Expected type doesn’t match actual value type
- Evaluation errors: Nix expressions that throw or have undefined behavior
- Bounds errors: Out-of-range access for indexed operations
§Examples
use nix_bindings_expr::eval_state::{EvalState, test_init, gc_register_my_thread};
use nix_bindings_store::store::Store;
use std::collections::HashMap;
test_init(); // init() in non-test code
let guard = gc_register_my_thread()?;
let store = Store::open(None, HashMap::new())?;
let mut es = EvalState::new(store, [])?;
// Evaluate a list expression
let list_value = es.eval_from_string("[1 2 3]", "<example>")?;
// Check the size (lazy - doesn't evaluate elements)
let size = es.require_list_size(&list_value)?;
println!("List has {} elements", size);
// Access specific elements (evaluates only accessed elements)
if let Some(first) = es.require_list_select_idx_strict(&list_value, 0)? {
let value = es.require_int(&first)?;
println!("First element: {}", value);
}
// Process all elements (evaluates all elements)
let all_elements: Vec<_> = es.require_list_strict(&list_value)?;
for element in all_elements {
let value = es.require_int(&element)?;
println!("Element: {}", value);
}
drop(guard);Structs§
- Eval
State - Eval
State Builder - Builder for configuring and creating an
EvalState. - Eval
State Weak - A Weak reference to an EvalState.
- Realised
String - A string value with its associated store paths.
- Thread
Registration Guard - RAII guard for thread registration with the garbage collector.
Functions§
- gc_now
- Triggers garbage collection immediately.
- gc_
register_ my_ thread - init
- test_
init - Initialize the Nix library for testing. This includes some modifications to the Nix settings, that must not be used in production. Use at your own peril, in rust test suites.