uni_plugin_rhai/lib.rs
1//! Rhai-script loader for the uni-db plugin framework.
2//!
3//! `uni-plugin-rhai` is the **host-embedded scripting loader**. It sits
4//! parallel to `uni-plugin-extism` (Extism bytes-in/bytes-out WASM) and
5//! `uni-plugin-wasm` (Component Model WIT) but takes a fundamentally
6//! different shape: there is no WASM wrapper, no IPC, no instance pool —
7//! the Rhai [`rhai::Engine`] is embedded directly in the host process.
8//!
9//! # Why Rhai
10//!
11//! Rhai fills the "dynamic AND sandboxed" loader quadrant:
12//!
13//! - **Pure Rust** — no C toolchain, no WASM wrapper, no separate runtime.
14//! Builds anywhere uni-db builds.
15//! - **Sandboxed by language design** — Rhai has no built-in I/O. Every
16//! effectful operation comes from a host-registered function. Registering
17//! a function is opt-in; *absence* is the default and matches the
18//! framework's capability-gating contract (proposal §10.2).
19//! - **Resource limits are first-class** on the `Engine`:
20//! `set_max_operations`, `set_max_call_levels`, `set_max_string_size`,
21//! `set_max_array_size`, `set_max_map_size`. No ad-hoc instruction-count
22//! shim.
23//! - **Actively maintained** on crates.io 1.x.
24//!
25//! # Capability gating — Engine-import absence
26//!
27//! The capability-enforcement layer 2 for Rhai is *Engine-import absence*:
28//! the loader registers a host function (`uni.fs.read`, `uni.http.get`,
29//! `uni.query`, …) on the per-plugin Engine **only when** the corresponding
30//! capability is in the effective grant set. A plugin without
31//! `Capability::Filesystem` cannot call `uni.fs.read` — Rhai raises
32//! `ErrorFunctionNotFound` at parse-resolution time. This is the in-host
33//! analogue of Component Model's linker-absence guarantee.
34//!
35//! # Crate status
36//!
37//! Implemented in phases. Phase 1 (this) ships the crate scaffold;
38//! phases 2+ wire the Engine factory, manifest parser, adapters, and
39//! `Uni::load_rhai_plugin`.
40
41// Rust guideline compliant
42#![warn(missing_docs)]
43#![warn(rust_2018_idioms)]
44#![warn(missing_debug_implementations)]
45
46pub mod error;
47pub mod host_fns;
48pub mod wire_translate;
49
50#[cfg(feature = "rhai-runtime")]
51pub mod host_fn_impls;
52
53#[cfg(feature = "rhai-runtime")]
54pub mod adapter;
55#[cfg(feature = "rhai-runtime")]
56pub mod adapter_aggregate;
57#[cfg(feature = "rhai-runtime")]
58pub mod adapter_procedure;
59#[cfg(feature = "rhai-runtime")]
60pub mod columns;
61#[cfg(feature = "rhai-runtime")]
62pub mod dynamic_bridge;
63#[cfg(feature = "rhai-runtime")]
64pub mod engine;
65#[cfg(feature = "rhai-runtime")]
66pub mod loader;
67#[cfg(feature = "rhai-runtime")]
68pub mod manifest;
69#[cfg(feature = "rhai-runtime")]
70pub mod runtime;
71
72#[doc(inline)]
73pub use error::RhaiError;
74#[doc(inline)]
75pub use host_fns::{RhaiHostFnRegistry, RhaiHostFnSpec};
76
77#[cfg(feature = "rhai-runtime")]
78#[doc(inline)]
79pub use adapter::RhaiScalarFn;
80#[cfg(feature = "rhai-runtime")]
81#[doc(inline)]
82pub use adapter_aggregate::{RhaiAccumulator, RhaiAggregateFn};
83#[cfg(feature = "rhai-runtime")]
84#[doc(inline)]
85pub use adapter_procedure::RhaiProcedure;
86#[cfg(feature = "rhai-runtime")]
87#[doc(inline)]
88pub use engine::{DEFAULT_MAX_CALL_LEVELS, build_engine};
89#[cfg(feature = "rhai-runtime")]
90#[doc(inline)]
91pub use loader::{LoadOutcome, RhaiLoader};
92#[cfg(feature = "rhai-runtime")]
93#[doc(inline)]
94pub use manifest::{AggregateEntry, ProcedureEntry, RhaiManifest, ScalarEntry};
95#[cfg(feature = "rhai-runtime")]
96#[doc(inline)]
97pub use runtime::RhaiPluginRuntime;