From and Into for type conversions

The From and Into traits provide a standard way to convert between types. Implementing From<T> for your type automatically provides Into<T> via a blanket implementation. I use From for infallible conversions (like String::from("hello")) an

std::fmt::Display for user-facing string representations

Implementing Display lets your types be formatted with {} in format strings. It's for user-facing output, unlike Debug which is for developers. I implement Display for error types, domain models, and anything that might be printed. The trait requires

Cargo.lock for reproducible builds

Cargo generates Cargo.lock to pin exact dependency versions. For binaries, commit the lock file so everyone builds the same dependencies. For libraries, don't commit it (users should resolve their own). The lock file enables reproducible builds: cargo

once_cell for lazy static initialization

once_cell provides Lazy and OnceCell for safe lazy initialization. Unlike lazy_static!, it doesn't require macros. Lazy<T> is initialized on first access via a closure. I use it for config, regex patterns, or expensive-to-create globals. OnceCel

tracing for structured logging and distributed tracing

The tracing crate is the modern standard for instrumentation in async Rust. It provides structured logging with spans (representing work) and events (point-in-time records). Spans can be nested, creating a tree that represents causality. I instrument

tokio::select! for racing multiple async operations

Tokio's select! macro lets you wait on multiple futures simultaneously, proceeding with the first one that completes. I use it for timeouts, graceful shutdown, and racing I/O operations. Each branch is a pattern match on the future's output. If multip

Pin and Unpin for safe self-referential async futures

Pin ensures that a value won't move in memory, which is required for self-referential types like async futures. Most async code hides this complexity, but understanding it helps when you hit compiler errors about Unpin. A type is Unpin if it's safe to

Declarative macros (macro_rules!) for code generation

Declarative macros (macro_rules!) let you write code that writes code, reducing boilerplate. They pattern-match on token trees and expand at compile time. I use them for repetitive patterns like implementing traits for multiple types or generating tes

Type state pattern for compile-time state machines

The typestate pattern uses Rust's type system to encode state machines, making invalid states unrepresentable. Each state is a separate type, and transitions consume self and return a new state. The compiler prevents calling methods that aren't valid

Builder pattern for complex struct initialization

For structs with many optional fields, the builder pattern provides a fluent API for construction. I define a separate Builder struct with methods that return self for chaining. The final build() method validates and returns the target struct. This is

Newtype pattern for type-safe primitives

The newtype pattern wraps a primitive in a tuple struct to create a distinct type. This prevents mixing up values that are semantically different but have the same underlying type (like UserId(u32) vs PostId(u32)). The compiler enforces that you can't

Rayon for data parallelism with par_iter

Rayon makes data parallelism trivial: replace .iter() with .par_iter(), and your loop runs in parallel across all CPU cores. It uses a work-stealing scheduler to balance load automatically. I use rayon for CPU-bound tasks like image processing, data t