Plugin Registry: Ecosystem Survey
rsconstruct uses a hand-built plugin registry where processors self-register
at link time via inventory::submit!, declare their config schema, and are
instantiated from TOML config at runtime. This page documents the search for
existing Rust crates that could replace this machinery.
What rsconstruct needs
The plugin system combines four responsibilities:
- Link-time self-registration — each processor file submits a plugin entry. No central list to maintain. Adding a processor = adding one file.
- Per-plugin TOML config — each plugin declares known fields, required
fields, defaults, and a
create(toml::Value) -> Box<dyn Processor>factory. The framework deserializes the matching[processor.NAME]section and passes it to the factory. - Defaults and validation — processor defaults, scan defaults, and output-dir defaults are applied in layers before deserialization. Unknown fields are rejected. Required fields are enforced.
- Name-to-factory mapping — the registry maps processor names to their
plugin entries for creation, introspection (
processors list), and config display.
Crates evaluated
inventory / linkme
The foundation rsconstruct already uses. inventory provides link-time
collection of typed values into a global iterator. linkme does the same
via distributed slices. Neither has any config awareness — they solve (1)
only.
- Verdict: already in use; does its job well.
spring-rs
The closest match conceptually. A Spring Boot-style Rust framework that
combines inventory-based plugin registration with TOML config via
#[derive(Configurable)] and #[config_prefix = "..."] attributes. Each
plugin declares its config struct with the derive macro, and the framework
auto-deserializes the matching TOML section.
However, spring-rs is a full application framework for web services (integrates axum, sqlx, OpenTelemetry, etc.). Pulling it in for a build tool would add a massive, opinionated dependency tree for ~50 lines of glue code savings.
- Verdict: right pattern, wrong scope. Not suitable.
config (crate)
Handles layered config loading from multiple sources (TOML, YAML, JSON, env vars) with type-safe deserialization. No plugin registration awareness at all — it’s a config library, not a plugin framework.
- Verdict: solves config layering, not plugin registration.
extism
A WebAssembly plugin runtime. Plugins are compiled to WASM and loaded at runtime with sandboxing. Completely different problem — runtime-loaded external plugins vs. compile-time self-registering internal plugins.
- Verdict: wrong problem domain.
plugin-interfaces
Designed for chat-client applications with FFI and inter-plugin messaging. Not relevant to build tools.
- Verdict: not applicable.
toml-cfg
Provides compile-time config macros (#[toml_cfg::toml_config]) that
embed config values from a TOML file at build time. No runtime registry,
no plugin awareness.
- Verdict: compile-time only; not what we need.
Conclusion
No existing crate provides the combination of link-time registration + per-plugin TOML config deserialization + defaults/validation + name-to-factory mapping. This is a genuine gap in the Rust ecosystem.
rsconstruct’s manual approach (~50 lines of glue in src/registries/processor.rs
using inventory::submit! + serde + the ProcessorPlugin struct) is the
standard Rust pattern for this. It is well-understood, has no external
framework dependency, and is unlikely to be improved upon by a third-party
crate without bringing in unrelated complexity.
Decision: keep the current hand-built registry. Revisit if a focused plugin-config crate emerges in the ecosystem.
Survey conducted: April 2026.