Config-file driven plugin loader for cordis-rs.
This crate is the assembly half of porting upstream Cordis' loader: it
connects cordis-include's entry trees to cordis fibers. Everything a
config-driven cordis application needs is re-exported here — depend on
cordis-loader alone.
How it works
- Static registry ([
PluginRegistry]) replaces upstream's dynamicimport(name): register plugins at startup, entries resolve by name. Thegroupbuiltin is pre-registered. - Startup: [
Loader::open] reads the entry file (writinginitialwhen missing), builds the [EntryTree], and starts every enabled entry — group entries ascordis_group::Groupfibers, children beneath their parent group's context, so disposing a group cascades. - Config: entries carry a
cordis_include::Nodeconfig (never()); loader plugins read it viaconfig.downcast::<Node>().${{ env.X }}templates expand at hand-off time; the file keeps the raw text. - Reload ([
Loader::reload], wired to thewatchfeature): re-read the file, diff the tree, and reconcile fibers — created entries start, removed subtrees stop, moved entries restart under their new parent, config-only changes patch in place viaFiber::update_value. - Inject: an entry's
injectlist is merged into the plugin's own declaration, so the core fiber machinery reconciles entries when services come and go — "hot-swapped service restarts its dependents" for free. - Self-kill vs. removal: a fiber that reaches
Disposedoutside loader operation was killed by its own plugin; the loader persistsdisabled: truefor that entry. Removing an entry from the file just stops it. - Write-back: [
Loader::update_config] is the runtime entry point — it updates the fiber and persists the config. Reloads never echo back (file-level suspend).
Example
use ;
let root = new;
let mut registry = new;
// registry.register_plugin(my_plugin); // your plugins, by name
let config = new.with_registry;
let loader = open?;
# assert!;
# Ok::
Register the plugins first (the group builtin is pre-registered), then
open; plugins registered later via [Loader::register_plugin] are picked
up by the next [Loader::reload].
Not in scope yet
The import entry kind (mounting a sub-file), isolate/service
migration, the loader/entry-init-style event family, and debounced
merged writes are future work.