Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pattern 19: Feature Gate Slices

Context

The framework offers advanced capabilities (property testing, mutation testing, testcontainers, OTEL) that not every project needs.

Problem

Enabling every feature increases compile times and pulls in heavy dependencies. Disabling a feature accidentally can break tests silently.

Solution

Group related features into named slices in Cargo.toml (e.g., testing-extras, observability-full). Document the slice and expose cfg-gated APIs accordingly. Tests and examples import the feature-specific modules only when the feature is active, keeping the base lean.

Forces

  • Modularity vs. convenience: slices reduce duplication but still allow fine-grained toggles
  • Discoverability vs. complexity: a small number of curated slices keeps onboarding simple
  • Compatibility vs. optionality: code must compile cleanly with features disabled

Examples

[features]
default = ["logging"]
testing-extras = ["property-testing", "snapshot-testing", "fake-data"]
observability-full = ["otel", "weaver"]
#![allow(unused)]
fn main() {
#[cfg(feature = "weaver")]
pub mod weaver;
}
  • Pattern 6: Generic Base Layer
  • Pattern 10: Capability Grouping
  • Pattern 20: Macro Pattern Enforcement