Skip to main content

Crate gen_platform

Crate gen_platform 

Source
Expand description

gen-platform — Rust-first canonical handle for the typed- dispatcher substrate primitive (typed-tagged-union catamorphism at a language boundary). Re-exports TypedDispatcher + #[derive(TypedDispatcher)], ships a runtime Dispatcher<T> applicator for Rust consumers (controllers, daemons, reactive routers, migration runners, RBAC engines, render passes), and surfaces typed catalog primitives so any pleme-io crate can stand up a typed dispatch surface against any closed variant universe with one cargo add.

§Why a dedicated crate

The mk-typed-dispatcher.nix primitive proves the value at the Nix dispatch layer. The same shape recurs across pleme-io wherever a closed variant set drives an action (see theory/QUIRK-APPLIER.md §IV-bis.1 for the catalog). gen-platform is the canonical Rust-side handle so consumers in pangea-operator, engenho controllers, magma plan walkers, anomalia remediations, shinka migrations etc. reach for the same primitive instead of hand- rolling another match ladder.

§Surface

use gen_platform::{Dispatcher, TypedDispatcher};

#[derive(serde::Serialize, serde::Deserialize, gen_platform::TypedDispatcher)]
#[serde(tag = "kind", rename_all = "kebab-case")]
enum Migration {
    AddColumn { table: String, column: String },
    DropIndex { name: String },
}

let dispatcher = Dispatcher::<Migration, MyCtx, MyOverride>::new()
    .helper("add-column", |variant, ctx| { /* ... */ Default::default() })
    .helper("drop-index", |variant, ctx| { /* ... */ Default::default() })
    .into_sealed()  // enforces variant coverage
    .expect("every variant has a helper");

let result = dispatcher.apply(&[migration_a, migration_b], &mut ctx);

§Re-exports

  • gen_types::TypedDispatcher — the reflection trait.
  • gen_types::DispatcherVariant — variant envelope shape.
  • gen_macros::TypedDispatcher#[derive] macro.

§New primitives (this crate)

  • Dispatcher<V, C, O> — runtime applicator. Holds typed helpers per variant kind. into_sealed() proves coverage at construction time (every reflected kind has a registered helper) — silent unknown variants become impossible.
  • SealedDispatcher<V, C, O> — the post-seal handle; apply cannot fail on coverage anymore (proven at seal time).
  • DispatcherError — typed error for build-time issues (missing coverage, duplicate helpers).
  • MergeStrategy — how to fold per-variant overrides.

Re-exports§

pub use catalog::by_label as catalog_by_label;
pub use catalog::registered as catalog_registered;
pub use catalog::DispatcherEntry;
pub use composed::ComposedDispatcher;
pub use composed::ComposedSource;
pub use dispatcher::Dispatcher;
pub use dispatcher::DispatcherError;
pub use dispatcher::SealedDispatcher;
pub use emit::to_helpers_skeleton;
pub use merge::MergeStrategy;

Modules§

catalog
DispatcherCatalog — inventory-style fleet-wide registry of every typed dispatcher in scope. Any pleme-io crate that #[derive(TypedDispatcher)]s an enum can register a catalog entry via the register_dispatcher! macro; gen-platform iterates them all at runtime through DispatcherCatalog::registered().
composed
ComposedDispatcher — closure-under-composition for the typed dispatcher catamorphism. Given N sealed dispatchers over disjoint variant universes, produce a single dispatcher that handles any variant from any of them by serde-tag dispatch.
dispatcher
Runtime Dispatcher<V, C, O> — the Rust-side peer of mk-typed-dispatcher.nix. Same catamorphism, native enum types.
emit
Emit substrate-side quirk-apply.nix skeletons from typed TypedDispatcher reflection. Closes the loop typed Rust enum → typed Nix dispatch arm without the operator hand-writing the mapping table.
merge
Typed merge strategies for folding per-variant overrides.

Macros§

register_dispatcher
Register a #[derive(TypedDispatcher)] enum into the fleet-wide dispatcher catalog. Place at module scope; one call per enum.

Structs§

DispatcherVariant
One variant of a typed Adapter quirk enum, surfaced via Adapter::dispatcher_reflection. Mirrors TypedDispatcher’s per-variant reflection without forcing the trait to carry a generic Quirk associated type.

Traits§

TypedDispatcherTrait
Reflection over a typed variant universe — typically a Rust enum declaring #[serde(tag = "kind", rename_all = "kebab-case")].

Derive Macros§

BackendError
#[derive(BackendError)] — auto-implement a trait with the shape:
Discriminant
#[derive(Discriminant)] — auto-implement pub const fn <method>(&self) -> &'static str returning the variant name as a stable case-folded identifier.
FromStrKind
#[derive(FromStrKind)] — the inverse of Discriminant. Parses a string back to a variant using the same case-folded variant name. Only unit variants are supported (data variants need caller-supplied payloads — out of scope for a string-only parse).
IsVariant
#[derive(IsVariant)] — auto-implement pub const fn is_<variant>(&self) -> bool for every variant.
OutcomeLattice
#[derive(OutcomeLattice)] — auto-implement an OutcomeLattice trait from per-variant severity attributes.
TypedDispatcher
#[derive(TypedDispatcher)] — auto-implement gen_types::TypedDispatcher on a Rust enum whose serde tag is #[serde(tag = "kind", rename_all = "kebab-case")].