CONTEXT.md: domain model with entities (WidgetConfig, DataSource, LayoutPreset), value objects (Layout, LayoutNode, KeyMapping, WidgetState, Sizing), architecture decisions (CQRS, static dispatch, postcard), client domain model, and design constraints.
24 lines
1.1 KiB
Markdown
24 lines
1.1 KiB
Markdown
# 0002 — Static dispatch over trait objects
|
|
|
|
**Status:** accepted
|
|
**Date:** 2026-06-18
|
|
|
|
## Context
|
|
|
|
Hexagonal architecture uses port traits extensively. Rust offers two ways to consume them: trait objects (`Box<dyn Port>`, dynamic dispatch) or generics (`T: Port`, static dispatch / monomorphization).
|
|
|
|
## Decision
|
|
|
|
Use generics for all port traits. No `Box<dyn>` anywhere. Composition roots (bootstrap on server, firmware crate on client) are the only places that know concrete types. Generic parameters propagate through application and presentation layers.
|
|
|
|
## Alternatives considered
|
|
|
|
**Trait objects** — simpler type signatures, less generic noise. But adds vtable indirection, heap allocation per trait object, and prevents compiler optimizations. On ESP32 with limited RAM, every allocation matters.
|
|
|
|
## Consequences
|
|
|
|
- Zero-cost abstractions — port calls are monomorphized, inlined where possible.
|
|
- More verbose type signatures — structs and functions carry generic parameters.
|
|
- Compile times may increase due to monomorphization.
|
|
- Consistent approach across server and client codebases.
|