add builder pattern for tvix_eval::Evaluation, allow passing in config to tvix_serde

Opened by flokli at 2023-03-20T12·29+00

Currently, tvix_serde creates an evaluation object with the passed source code and immediately starts to evaluate:

    let eval = tvix_eval::Evaluation::new(src, None);
    let source = eval.source_map();
    let result = eval.evaluate();

    if !result.errors.is_empty() {
        return Err(Error::NixErrors {
            errors: result.errors,

This means, it's not possible to pass in custom builtins etc.

It might make more sense to have tvix_eval provide a Builder Pattern to assemble EvalConfig, containing all this config, and consume such a config in tvix_serde.

We could also expose a "pure eval, no IO, no build/store related builtins" default config (by implementing Default.

That way, WASM or serde clients could just say EvalConfig::default(), and the CLI could compose another one.

  1. After playing with these thoughts a bit, I think we want to have a longer-living struct Evaluator struct, that is constructed from a EvalBuilder::build(). config in Evaluator should be considered immutable after creation.

    We could then move compile_only and evaluate to Evaluator::{compile_only,evaluate}, and add the attribute path/source code to the function arguments - probably together with optional observer(s) - but these could be called without consuming self.

    This should open up possibilities to longer-running evaluators, some simple LSP workloads etc - and we could pass such an Evaluator into tvix-serde - and derive Default, if we want to.

    flokli at 2023-05-27T17·23+00