Skip to content

Rust Style and Best Practices

This page documents paiOS-specific Rust preferences on top of the official Rust style guide and Development Standards. Use it when making tradeoffs the style guide doesn’t mandate.

We prefer stack allocation when it doesn’t hurt maintainability, especially for embedded and performance-sensitive paths.

  • Stack: Fixed size at compile time, no allocator, cache-friendly. Use for concrete types and when the full type is known at compile time.
  • Heap (Box, Vec, etc.): Needed for dynamic size, shared ownership, or when you must pick an implementation at runtime. Use when stack isn’t practical.

On resource-constrained or embedded targets, prefer stack and fixed-capacity types (e.g. heapless) where possible; avoid unnecessary heap.

When the concrete type is known at compile time (e.g. composition root wired with #[cfg(feature = "...")]), prefer generics so implementations can live on the stack:

// Preferred when the composition root knows concrete types at compile time
pub struct Orchestrator<V, A, I, Api, P> {
vision: V,
audio: A,
inference: I,
api: Api,
peripherals: P,
}
impl<V, A, I, Api, P> Orchestrator<V, A, I, Api, P>
where
V: VisionInterface,
A: AudioInterface,
I: InferenceInterface,
Api: APIInterface,
P: PeripheralsInterface,
{
pub fn new(vision: V, audio: A, inference: I, api: Api, peripherals: P) -> Self {
Self { vision, audio, inference, api, peripherals }
}
}

Use Box<dyn Trait> when you must choose the implementation at runtime (e.g. from config or user input), or when threading many generic parameters would make the API unwieldy and the allocation cost is acceptable.

SituationPreferReason
Composition root, one concrete type per build (e.g. feature flags)Generics (stack)No heap, one monomorphized type per profile.
Runtime selection of implementationBox<dyn Trait>Single type, flexible.
Many dependencies, type list explodesBox<dyn Trait>Keep APIs and call sites manageable.
  • Run cargo fmt (we use default rustfmt settings).
  • Aim for zero clippy warnings; fix or document exceptions.
  • See Development Standards for DoD and required checks.
  • Public and notable internal items: Use /// or //! doc comments. See Documentation Guide for Starlight sync.
  • For terminal snippets in rustdoc, prefer bash frame="none" where possible (see project Cursor rules).