Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Link-time self-registration — each processor file submits a plugin entry. No central list to maintain. Adding a processor = adding one file.
  2. 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.
  3. 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.
  4. 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.