graphddb_runtime 0.7.7

Rust runtime for GraphDDB — interprets the language-neutral IR (manifest.json + operations.json) and executes the validated access patterns against DynamoDB.
Documentation

GraphDDB Rust Runtime

A Rust (edition 2021) runtime that interprets the language-neutral GraphDDB IR (manifest.json + operations.json, SPEC_VERSION 1.1) and executes the validated access patterns against DynamoDB via aws-sdk-dynamodb. It is a faithful port of the Python reference runtime (python/graphddb_runtime) and is proven, by the conformance harness (conformance/), to produce results identical to the TypeScript live executor and the Python / PHP runtimes for every golden case.

TypeScript remains the single source of truth: this runtime never re-implements the GraphDDB DSL — it is a pure interpreter of the IR the TS generator emits, so src/ is never touched (issue #214, epic #211).

Layout

  • graphddb_runtime/ — the library crate (the runtime).
  • conformance_runner/ — the rust_runner binary the conformance harness drives (the structural counterpart of conformance/py_runner.py / php_runner.php).

Usage

use std::sync::Arc;
use aws_sdk_dynamodb::Client;
use graphddb_runtime::{AwsDynamoClient, GraphDDBRuntime, RuntimeLimits};
use serde_json::json;

# async fn demo() -> Result<(), Box<dyn std::error::Error>> {
let conf = aws_config::load_from_env().await;
let client = Arc::new(AwsDynamoClient::new(Client::new(&conf)));

let runtime = GraphDDBRuntime::from_paths(
    client,
    "manifest.json",
    "operations.json",
    None,                       // optional logical→physical table mapping
    Some(RuntimeLimits::default()),
)?;

// Params are keyed by the original definition names; results are serde_json::Value.
let user = runtime
    .execute_query("getUser", json!({"userId": "alice"}).as_object().unwrap())
    .await?;

runtime
    .execute_command("addGroupMember", json!({"groupId": "eng", "userId": "u1", "role": "member"}).as_object().unwrap())
    .await?;
# Ok(()) }

The consumer API mirrors the Python surface: execute_query, execute_command, execute_transaction, execute_query_method, execute_command_method, and explain (all async). Typed bindings (the Python types.py / repositories.py layer) are out of scope for this crate — the runtime works directly on the IR.

Development

cargo build
cargo test          # unit tests + the python3 number-parity fuzz (skips if no python3)
cargo clippy --all-targets -- -D warnings
cargo fmt --all --check

Number / cursor parity

Pagination cursors and DynamoDB number encoding are byte-identical to the Python reference (the parity SSoT):

  • a cursor N token is an exact full-precision integer when the value is integral, else float(Decimal(x)) rendered by CPython's json.dumps(float) formatter (deliberately lossy — see ddb_number.rs);
  • float → string reproduces CPython's repr(float) exactly, including its fixed-vs-scientific threshold, signed zero-padded exponents, and the round-half-to-even shortest-digit tie-break (pyfloat.rs).

Every numeric test vector is regenerated from python3 at test time (a fuzz over thousands of doubles / decimal strings) — never pinned to Rust's own output.

Conformance

The Rust dimension is wired into conformance/run.ts (tag rust:). Bring up DynamoDB Local (npm run docker:up) and run:

npx tsx conformance/run.ts

The Rust results are deep-compared against the TS live executor for every case, alongside the Python and PHP dimensions. CI (.github/workflows/rust.yml) runs build/test/clippy/fmt, the conformance harness, a rust-* mutation non-vacuity probe, and the git diff -- src/ guard.