Mix language library

mix is the embeddable Rust implementation of the Mix language at libs/mix. It tokenises, parses, analyses and evaluates Mix source, exposes the Mix value and error models, and supplies host interfaces for Bus and other mediated services. Bus-facing behaviour enters through injected traits, so embedders can use the evaluator without moving protocol or daemon dependencies into this crate.

The Cargo package and Rust library are both named mix. The shell is the separate mix-shell library, and the system package builds its executable.

Synopsis

use mix::{MixResult, run_capturing};

async fn evaluate() -> MixResult<()> {
    let (_value, stdout, stderr) =
        run_capturing("print(1 + 2)\n").await?;

    assert_eq!(stdout, "3\n");
    assert!(stderr.is_empty());
    Ok(())
}

For strict Mix data:

use mix::{MixResult, parse_data};

fn load_data() -> MixResult<String> {
    let value = parse_data(r#"{service: "alpha", retries: 3}"#)?;
    value.to_mix_data_string()
}

Entry points

ItemPurpose
run(source)Tokenises, parses, and evaluates Mix source with a new default Evaluator.
run_capturing(source)Evaluates source and returns the result value plus captured stdout and stderr.
parse_data(source)Parses only the literal-data subset and returns a Value.
parse_data_file(path)Reads a Mix data file and applies parse_data.
Lexer::tokenizeConverts source text into spanned tokens.
Parser::parse_programConverts tokens into a statement AST.
Parser::parse_dataParses tokens under strict-data rules.
analyzer::analyzeProduces conservative semantic diagnostics and a capability inventory.
Evaluator::executeExecutes parsed statements in a configured evaluator.

parse_data accepts scalar literals, lists, maps, and nested combinations. It rejects variable reads, calls, messaging, shell execution, interpolation, control flow, and arithmetic with MixError::StrictDataViolation.

Value::to_mix_data_string and Value::to_mix_data_string_pretty emit strict-data text that can be parsed again. Human-oriented Value::write_mix output is a separate format and is not the strict-data round-trip path.

Evaluator

Evaluator is the configurable interpreter host. Evaluator::new uses normal process output; Evaluator::with_output accepts separate Write sinks. SharedBuf provides an in-memory sink for captured bytes.

The evaluator supports:

  • async native extensions through ExtFn, sync_ext, and Evaluator::register;
  • global injection and lookup through set_global and get_global;
  • source identity, tracing, usage statistics, and prelude loading;
  • compatible or strict function arity through ArityMode;
  • recursion, wall-clock, list, map, and string limits through EvalLimits;
  • builtin authority checks through CapabilityPolicy;
  • Bus, database, JMAP, delegated Bus-call, shell, and serve-runtime host traits;
  • direct event dispatch and an incoming Bus event pump.

The default capability policy is permissive. CategoryAllowList allows pure builtins plus selected CapabilityClass values: fs-read, fs-write, network, process, env, db, jmap, and bus.

The capability policy is an in-process robustness boundary for trusted embedded scripts. It is not process isolation for untrusted code.

EvalLimits checks wall-clock time at statement polls. A single blocking builtin cannot be interrupted in the middle of its blocking operation.

Host seams

BusHandler connects language-level messaging to a host. It covers request/reply sends, fire-and-forget emits, port checks, incoming events, service registration, topic subscription, correlated replies, and reconnect requests.

BusCallHandler backs the scoped bus_call(verb, args) builtin. The host chooses the reachable verbs and supplies trusted delegation context; the script supplies only the verb and arguments.

DbHandler backs db_query and db_exec with positional bind values. Queries return lists of row maps. Executions return a map containing affected-row and last-insert information.

JmapHandler backs JMAP method batches and blob uploads without exposing network credentials or an arbitrary destination to the script.

ShellHandler classifies, validates, and executes shell lines when a host enables mixed source handling. Without a registered handler, sourced files retain strict Mix semantics.

ServeRuntime handles runtime-reserved Bus verbs before author-defined handlers. It returns ReservedOutcome values containing a Bus return code, response body, and graceful-quit flag.

The evaluator and its boxed host futures use single-threaded Rc and RefCell state. Host implementations are therefore not required to return Send futures.

Values and errors

Value represents strings, numbers, booleans, lists, maps, functions, raw bytes, mutable byte buffers, and nil. Lists, maps, and raw bytes use reference-counted copy-on-write storage. Buffers use shared reference semantics, so mutations are visible through aliases.

MixError covers lexing, parsing, strict-data, and runtime failures. MixResult<T> is the crate result alias. Structured runtime errors use stable codes, optional details, source spans, and traceback frames through ErrorInfo.

IndexMap is re-exported so embedders can construct the ordered map used by Value::Map without coupling to a separate indexmap version.

Builtin discovery and policy

builtins contains the builtin registry and dispatch implementation. builtins_hof contains async higher-order builtins that can call back into Mix functions.

Every builtin has a BuiltinInfo and BuiltinContract. The contract records arguments, return shape, effect flags, operational-failure behaviour, conditional capabilities, and any non-contiguous accepted arities. BuiltinInfo::signature derives a human-readable signature from this metadata.

capability_category, conditional_capabilities, conditional_cap_engaged, and builtin_info_of expose the registry to embedders. CategoryAllowList is the supplied class-based policy.

Modules

ModuleSurface
analyzerSemantic diagnostics, analyzer configuration, and script capability inventory.
astExpression, statement, function-body, operator, and assignment-path nodes.
builtin_infoBuiltin metadata, contracts, type shapes, effects, and signature rendering.
builtinsCore builtin dispatch, metadata tables, capability classes, and helpers.
builtins_hofHigher-order builtin registry with evaluator callbacks.
errorSource spans, structured error information, traceback frames, and MixError.
evaluatorInterpreter, limits, extensions, host traits, event handling, and output capture.
interruptProcess-wide SIGINT cooperation for evaluator and blocking builtin polling.
lexerSource tokenizer.
parserProgram and strict-data parser.
scopeVariables, functions, call frames, and scope storage.
statsSession and language-usage counters.
tokenTokens, spanned tokens, and interpolated string parts.
valueRuntime value representation and Mix data serialisation.
jsonJSON conversion when the json feature is enabled.
jqEmbedded jq-compatible filtering when the json feature is enabled.
serde_deSerde deserialisation from Value when the serde feature is enabled.
serde_serSerde serialisation to Value and .conf.mix text when serde is enabled.

Cargo features

The default feature set is empty. Tokio remains an unconditional dependency because evaluator task, synchronisation, timer, and macro APIs are part of the core implementation.

FeatureAdds
defaultNo optional features.
jsonJSON conversion, JSON and JSONL builtins, jq filtering, and JSON-backed stats helpers.
regexre_match, re_find, re_replace, and re_split (subject first); without it grep_lines falls back to a per-line substring test. The pattern-first regex_* names were deleted in 0.73.0.
markdownSafe CommonMark and GFM rendering through markdown; raw HTML is escaped and dangerous URL schemes are neutralised.
tomltoml_parse and toml_encode.
serdeSerde Deserializer and Serializer bridges for Value and strict .conf.mix text.
datetimeDate parsing and formatting, ISO timestamps, duration formatting, and relative time.
urlStructured URL parsing through url_parse.
cryptoBase64, BLAKE3, SHA-256, HMAC-SHA-256, constant-time comparison, file hashing, and UUID generation.
httpHTTP GET, POST, and general request builtins with web roots and optional PEM CA loading.
sqliteDirect SQLite open, execute, and close builtins.
tokio-sleepBackwards-compatible feature alias; it adds no dependency or code gate.
dkimRSA-2048 and Ed25519 DKIM key generation plus DNS TXT record text.
datastarDatastar element patches, signal patches, and SSE serialisation; also enables json.
xmlStrict XML parsing in simple or full-fidelity tree mode. It is not an HTML parser.

Analysis

The semantic analyzer sits between parsing and evaluation and can be used without the command-line frontend. It reports definitely undefined variables and callables, arity mismatches, duplicate declarations, unreachable statements, discarded must-use results, and statically resolvable require failures.

AnalyzerConfig declares host-provided globals and functions. Analysis returns diagnostics plus the capability classes used by the script. The analyzer favours very low false-positive rates for dynamic language constructs.

Testing support

The crate contains unit and integration coverage for parsing, evaluation, strict data, limits, capabilities, host seams, structured errors, and optional builtins.

The nested fuzz workspace supplies fuzz_lex and fuzz_parse libFuzzer targets. It runs on demand with a nightly Rust toolchain and is not part of the parent workspace's normal test gate.

Package limits

This package defines no binary target, command-line subcommands, command-line configuration, daemon process, or standalone configuration loader. Those surfaces belong to hosts that embed mixos_mix.

This page as Markdown · This page describes the current main branch of MixOS.