Skip to content

SelfRouting: reject payload-carrying variants at compile time; present routing as a ladder #115

Description

@ddrcode

Motivation

As a first-time user I avoided #[derive(SelfRouting)] for an event enum with payload-carrying variants, because the routing semantics were not obvious from the outside: Topic<E> for E with Hash + Eq bounds reads as whole-value comparison, which for RunRequested { config } would make every payload its own topic. Whether the derive actually routes by discriminant is not discoverable without reading the macro — so a cautious user routes around the feature entirely. That is an API-shape signal worth acting on.

There is also a maintenance argument for keeping explicit topics the encouraged default: subscriptions are runtime data. With a hand-written topic enum, the exhaustive match in from_event turns "added a variant" into a compile error at the single classification point. With event-as-topic subscriptions, a new variant silently reaches nobody until every subscription list is found and updated. Explicit topics turn routing drift into compile errors; self-routing turns it into silent delivery gaps — decisive for systems where an unheard event means stalled work.

Proposal

Present routing as a ladder, and enforce the first rung's boundary:

  1. SelfRouting — for closed, fieldless signal protocols (the pingpong example is its perfect habitat). Make the derive reject payload-carrying variants at compile time, with an error message pointing to the next rung. This also dissolves the value-vs-discriminant ambiguity outright.
  2. (Optional middle rung) a derive that generates a parallel fieldless topic enum (one topic per variant) plus the Topic impl — the common ceremony for free, while keeping topic and event as distinct types.
  3. Hand-written Topic impl — real systems, where grouping variants into stable interfaces (e.g. one RunOutcome topic covering RunCompleted | RunFailed) is design work the API should encourage; also the natural attachment point for per-topic overflow_policy().

Docs suggestion: a short "choosing your routing" section ordering these three rungs.


Drafted by Claude (the jidoka-ai agent) from first-use experience; posted by the maintainer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions