core linkml schema operations written in rust
The showcase notebook demonstrates the Python bindings (linkml-runtime-rust on PyPI): schema loading without I/O, multi-schema namespace support with cross-schema slot disambiguation, instance loading/validation, diffing & patching, and Turtle export.
- linkml_meta (
src/metamodel): Autogenerated LinkML metamodel types and helpers. Optional Serde/PyO3 features for serialization and Python interop. - schemaview (
src/schemaview): Schema loading, CURIE/URI conversion, resolution (feature-gated), and view utilities:SchemaView,ClassView,SlotView,EnumView. - linkml_runtime (
src/runtime): Core runtime:LinkMLInstanceparsing (YAML/JSON), basic validation, diff/patch, and Turtle serialization. Pure Rust library. - linkml_tools (
src/tools): CLI tools wrapping the runtime and schemaview:linkml-validate,linkml-convert,linkml-diff,linkml-patch,linkml-schema-validate.
- linkml_runtime_python (
src/python): PyO3 bindings and Python package (linkml_runtime_rust._native) exposing SchemaView and LinkMLInstance to Python; includes small Python helpers. - linkml_wasm (
src/wasm): WASM build target (experimental).
SchemaView instances can be serialized into a snapshot—a self-contained YAML payload that carries
every loaded schema definition along with the resolved-import lineage and primary-schema pointer. The
snapshot can be reconstructed into an equivalent SchemaView without contacting remote import targets,
making it ideal for building views server-side and shipping them to Python, WASM, or browser clients.
- Rust:
SchemaView::to_snapshot_yaml()/SchemaView::from_snapshot_yaml(...) - Python:
SchemaView.to_snapshot_yaml(),SchemaView.from_snapshot_yaml(...) - WASM/JS:
JsSchemaView::toSnapshotYaml(),schemaview_from_snapshot_yaml(...)
src/metamodel (the linkml_meta crate) is generated and must never be edited by hand.
The generator is gen-rust, which lives in a linkml
checkout rather than in this repo; the input schema is src/schemaview/tests/data/meta.yaml.
- Put a linkml checkout at
../linkmlon a branch carrying the rust generator, or pointLINKML_DIRat one. Recreate its venv withcd ../linkml && uv syncif it is missing. - Regenerate in place:
./regen.sh - Check reproducibility:
./regen.sh --check— regenerates into a temp dir, formats it the same way, and diffs against the committed crate without writing anything.
An empty --check diff means the committed crate is exactly what that generator emits. A
non-empty one means either the checkout is on a different revision than the crate was built
from, or something was hand-edited into generated code — and a regen would silently revert
it. That has happened before (a per-key map merge strategy), which is why the check exists.
./regen.sh stamps src/metamodel/GENERATED_FROM with the generator revision it used and
with every generator change it needed that is not in linkml/main, each resolved to the pull
request carrying it. That list is the reproduction recipe: apply those PRs on top of
linkml/main and re-run the script.
So a generator fix does not have to be merged upstream before the regenerated crate lands
here — it has to be identifiable. Push it and open the PR, so the stamp can name something a
reader can fetch instead of a sha that only exists on your disk. (LINKML_PR_REPO overrides
which repo is searched for the PR; it defaults to linkml/linkml.)
Each such PR gets a tracking issue here, so they can be closed off one by one as they merge upstream and drop out of the stamp.
- Create a virtual env and activate it
- Install maturin (pip install maturin)
- From repo root, run:
maturin develop -m src/python/Cargo.toml(or use your venv:../env/bin/maturin develop -m src/python/Cargo.toml)
Now the linkml_runtime_rust module should be accessible.
- Build all crates:
cargo build --workspace - Run all tests:
cargo test --workspace - Format:
cargo fmt --all(check:cargo fmt --all -- --check) - Lint:
cargo clippy --workspace --all-targets --all-features --exclude linkml_meta -- -D warnings --no-deps(excludes autogeneratedlinkml_meta)