vynil-core
A Rust toolbox for bootstrapping projects that combine a Rhai scripting engine and a Handlebars templating engine, with optional Kubernetes / OCI / S3 handlers.
vynil-core is the generic layer extracted from vynil so it
can be reused by other projects (kuberest, kydah, …) without pulling in vynil's business
abstractions (CRDs, package model, instance controllers).
Status: extracted from the vynil workspace and published independently. The public API is not yet stable — expect breaking changes before 1.0.
What it provides
- Rhai engine —
Script::new_bare(resolver_paths)with the generic helpers (datetime, hashes, password, ed25519 keys, semver, glob, shell, serde-YAML, base64/json, file I/O). - Handlebars engine —
HandleBars::new()with the generic helpers (base64, bcrypt, argon, password, encoding, concat, plus thehandlebars_misc_helpersset) andengine_mut()to extend it. - HTTP —
RestClient(reqwest) and its mockRestClientMock.
A plain vynil-core = "x" dependency (default features) gets all three, unchanged from previous
releases. Each is independently optional for a consumer that only needs one — see below.
Features
| Feature | Default | Adds | Pulls in |
|---|---|---|---|
rhai |
on | The Rhai scripting engine (Script) and every other module's Rhai bindings |
rhai |
hbs |
on | The Handlebars templating engine (HandleBars) |
handlebars, handlebars_misc_helpers, jmespath, toml |
http |
on | RestClient (reqwest) + its mock. Implies rhai — RestClient stores its headers as a Rhai Map internally |
reqwest, schemars, tokio, rhai |
crypto |
on | argon_hash/bcrypt_hash/gen_private_key (Handlebars "always" helpers) and the matching Rhai bindings |
openssl, argon2, bcrypt |
k8s |
off | generic K8s handlers + their mocks. Implies rhai — K8sGeneric is a Rhai-facing API throughout |
kube, k8s-openapi, futures, tokio, rhai |
oci |
off | Registry + OCI mock. Implies rhai, same reasoning as k8s |
oci-client, tokio, rhai |
s3 |
off | S3 client. Implies rhai, same reasoning as k8s |
object_store, futures, tokio, rhai |
fs |
off | Filesystem access from Rhai scripts | — |
shell |
off | Shell command execution | — |
password |
off | gen_password/gen_password_alphanum (off by default to avoid a name collision with a consumer's own password semantics) |
rand |
# default: Rhai + Handlebars + HTTP + crypto helpers, same as previous releases
= "0.7"
# Kubernetes project
= { = "0.7", = ["k8s"] }
# Handlebars only (e.g. rendering MCP tool output), no Rhai engine at all
= { = "0.7", = false, = ["hbs", "crypto"] }
Client identity
vynil-core performs HTTP calls (and, with the k8s feature, Server-Side-Apply calls) on
behalf of the consuming application. It does not assume an identity for you — call
vynil_core::set_client_name(...) once at startup, before issuing any request:
set_client_name;
Any RestClient or k8s call made before this is configured will panic with a message
explaining what to do.
Minimal example
let mut script = new_bare;
script.engine.register_fn; // register your own helpers
script.run_file?;
let mut hbs = new;
hbs.engine_mut.register_helper;
let output = hbs.render?;
What it does NOT include
The vynil-specific layer stays in vynil: CRDs, VynilContext, VynilPackage, the instance
macros, the order-preserving YamlDoc, and the context-aware Handlebars helpers
(selector_from_ctx, labels_from_ctx, image_from_ctx, …). Consumers add their own on top of
the Script/HandleBars engines.
License
BSD 3-Clause (same as vynil).