Railway-Oriented Programming in Rust: Boundaries First
rust-railway is fundamentally a boundary enforcement framework that happens to look like a pipeline library. Boundary appears in 83% of architectural entities. The compiler proves every junction is type-safe before the first payload flows.
Railway-Oriented Programming in Rust
Railway-oriented programming for Rust — deterministic routing of payloads through sequential processing stages where failures shunt to a parallel track without halting the system, enforced at compile time through Rust's ownership model.
The Core Finding
rust-railway is fundamentally a boundary enforcement framework that happens to look like a pipeline library. Boundary appears in 10 of 12 architectural entities — 83% dominance.
The value is not "chain functions together." The value is "the compiler proves every junction is type-safe before the first payload flows."
Four Layers, Twelve Entities
| Layer | Entities | Dependency Level |
|---|---|---|
| Primitive (L0-L1) | Track, Switch, Signal, Coupling, Depot | 0-1 |
| Composition (L2-L3) | Line, Junction, Gauge, Timetable, Ballast | 2-3 |
| DSL (L4) | railway! macro | 4 |
| Cross-cut (L5) | Rolling Stock (#[derive(Payload)]) | 5 |
Three Recurring Compositions
| Pattern | Primitives | What It Does |
|---|---|---|
| Typed Pipeline | Boundary + Sequence | Track, Coupling, Line — data flows through typed stages |
| Routing | Comparison + Aggregation | Switch, Junction, Gauge — payloads route based on content |
| Provenance | State + Persistence | Signal, Depot, Rolling Stock — history travels with data |
Primitive Frequency
Across all 12 entities:
Boundary (83%) dominates. Then Sequence (42%). Then Aggregation and Mapping (33%). Then Causality, Frequency, State, and Quantity (25%).
The least-used primitives — Irreversibility, Existence, Self-reference, Void — are the ones that railway architecture deliberately eliminates. A railway removes irreversibility (you can always shunt to the error track), eliminates void states (every payload has a destination), and avoids self-reference (pipelines are acyclic).
Three Load-Bearing Voids
- Backpressure — what happens when payloads arrive faster than the timetable processes them?
- Dead letter — where does a payload go after exhausting all retry attempts?
- Microgram bridge — 448 YAML decision trees need an adapter to become railway Switches
These voids are not bugs. They are design decisions that have not yet been made. Identifying them before building prevents the three most common failure modes in pipeline architecture.
Why Boundary Dominance Matters
When one primitive dominates at 83%, it tells you what the system IS at its core. rust-railway is not a pipeline library. It is a boundary library that expresses boundaries as pipelines. The pipeline is the notation. The boundary enforcement is the value.
This has practical implications: optimize for boundary correctness first, pipeline throughput second. A fast pipeline with leaky boundaries is worse than a slow pipeline with airtight boundaries — because boundary violations compound while throughput issues are linear.