# decl-lang
**Decl** is a declarative language for describing, generating, and
validating structured data — a JSON superset with a strong static type
system, constraints with first-class diagnostics, references, physical
quantities, generics, and modules. Pure, deterministic, terminating.
This crate is the **native Rust implementation** of the whole language:
the tree-sitter grammar is compiled in, `decl` checks, evaluates,
validates, and formats modules (packages included), and `decl-lsp` is
the language server — no Node.js or wasm involved.
```bash
cargo install decl-lang
```
## Command line
```bash
decl check schema.decl # static checks, module-aware (exit 1 on errors)
decl evaluate site.decl # evaluate every output -> {"name": value, ...}
decl evaluate site.decl --output site # one output -> its canonical JSON on stdout
decl evaluate site.decl --json # {"ok", "value", "diagnostics"} report
decl evaluate cfg.decl --input deployed=doc.json --output deployed=out.json # bind a document, write its completed value
decl validate cfg.decl --input deployed=doc.json # bind a document to an input root (diagnostics only)
decl validate tests/validation # judge a fixture corpus
decl fmt src/*.decl # canonical formatting in place (--check: exit 1 if not canonical)
decl repl site.decl # an interactive session: expressions, bindings, edits, undo
decl-lsp # language server over stdio
```
Diagnostics go to stderr as `file: severity [code] id at path: message`,
or into the JSON report with `--json`. The exit code is 1 when any error
was reported.
## Library
```rust
use decl_lang::{evaluate, check, validate, format_source, Document, EvaluateOptions};
let docs = evaluate("site.decl", &EvaluateOptions::default())?; // exported outputs, by name, as canonical JSON text
let site = &evaluate("site.decl", &EvaluateOptions { outputs: vec!["site".into()], ..Default::default() })?["site"];
let done = evaluate("cfg.decl", &EvaluateOptions {
inputs: vec![("deployed".into(), Document::File("doc.json".into()))], // or Document::Json(text)
outputs: vec!["deployed".into()],
})?;
let problems = check(&["schema.decl"]); // empty when clean
let report = validate("cfg.decl", &[("deployed".into(), Document::Json("{\"host\":\"h\"}".into()))])?;
let text = format_source("const x=1+2\n")?; // "const x = 1 + 2\n"
```
The functions are the `decl` command line in its own vocabulary:
`inputs` binds documents by input name (a JSON file, or JSON text),
`outputs` names the roots to return — outputs, or inputs bound here or
demanded through their fallback — and defaults to the entry module's
exported outputs; a failure is a `DeclError` whose `diagnostics` carry
the report. The npm package (`evaluate`, …) and the PyPI package
(`decl.evaluate`, …) offer the same functions with the same semantics;
the modules the functions are built from are public as well.
## Scope
The crate covers the whole language: parsing, the static checks of
chapters 3–4 (type resolution with generics and dimension algebra,
inference, assignability, the absence discipline, `match`
exhaustiveness), binding with lazy slots and cycle detection,
`$referrers`, assertions with diagnostic templates, canonical
serialization, modules and packages (`decl.toml`, `decl.lock`), the
canonical formatter, and the language server. Its output is
byte-identical to the reference implementation — the repository's
parity harness (`tests/parity/differential.py`, run by `make verify`)
diffs the Rust and Python runtimes against the reference over every
example and fixture that produces output.
## Building from source
The grammar's C sources are compiled by `build.rs`. Inside the
repository they come from `../tree-sitter-decl/src`; the published crate
carries a copy under `grammar/` (generated by `npm run build` in
`decl-ts/`).
```bash
cargo build --release # from the repository root (Cargo workspace)
./target/release/decl evaluate docs/examples/02_config.decl --output prod
```
## License
MIT — see `LICENSE`.