2.6 KiB
Embedding API
Decodal core can be embedded without giving the core crate access to a filesystem.
The host supplies imported sources through SourceLoader and may also provide global bindings through the host prelude API.
Host prelude
Engine owns a prelude environment.
Bindings in this environment are visible from every module loaded by the engine.
prelude env
↓
module root env
↓
let / function env
Module top-level bindings shadow prelude bindings.
Primitive type names such as String, Int, Float, and Bool are handled before environment lookup, so they are reserved and cannot be shadowed by host bindings.
Global bindings
The host can bind values before adding or evaluating user sources.
use decodal_core::{EmptyLoader, Engine, HostValue};
let mut engine = Engine::new(EmptyLoader);
engine.bind_global(
"Service",
HostValue::object([
("name", HostValue::string_type()),
("port", HostValue::int_type().gt(443).default_int(8443)?),
("enabled", HostValue::bool_type().default_bool(true)?),
]),
)?;
A user source can then refer to Service without importing it.
Service & {
name = "api";
port = 9443;
}
HostValue
HostValue is the public builder-facing value representation for embedding.
It keeps host code from constructing internal ThunkId or ObjectValue values directly.
HostValue =
String
Int
Float
Bool
Array(Vec<HostValue>)
Object(Vec<HostField>)
Abstract { constraints, default }
When a host value is bound, the engine internalizes it into RuntimeValue and allocates value thunks for object fields, array items, and defaults.
Abstract host objects
A host-provided schema object is represented as a concrete object structure whose fields may contain abstract values.
HostValue::object([
("name", HostValue::string_type()),
("port", HostValue::int_type().gt(443).default_int(8443)?),
])
Conceptually this becomes:
Concrete(Object {
name -> Thunk(Abstract { constraints: [String], default: none })
port -> Thunk(Abstract { constraints: [Int, > 443], default: 8443 })
})
This matches the runtime model used for Decodal source-defined schema objects.
SourceLoader and prelude together
SourceLoader and host prelude bindings are independent mechanisms.
- Use
SourceLoaderwhen user sources should explicitly import host-provided modules. - Use prelude bindings when host-provided schemas or constants should be globally available.
Both mechanisms share the same runtime evaluator, thunk model, and materialization rules.