Generics, Trait Objects, and Values
The command boundary uses dynamic dispatch because declarations are discovered
by name at runtime. EngineState stores cloneable Box<dyn Command> values;
CommandClone provides object-safe cloning. Each command advertises a concrete
Signature, documentation, examples, and a common run method.
Inside commands, generics recover static composition. Iterator adapters are
generic until ListStream::new erases them. Evaluation is generic over a
DebugContext marker so normal and debug execution share code without a
runtime branch at every operation. Conversion traits such as
IntoPipelineData, IntoValue, and typed CallExt flag access connect Rust
types to shell values.
Closed runtime diversity uses enums: Value, PipelineData, ShellError,
OutDest, expressions, and byte-stream sources. Exhaustive matches are valuable
because adding a new data mode must force every core boundary to consider it.
The pattern is layered: trait objects for a runtime registry, enums for the language’s closed data model, generics for implementation helpers, and boxed iterators exactly where arbitrary lazy pipelines must share one representation.