VecDeque<T> for double-ended queue operations

VecDeque&lt;T&gt; is a growable ring buffer supporting efficient push/pop from both ends. I use it for queues, breadth-first search, and sliding windows. Methods: .push_front(), .push_back(), .pop_front(), .pop_back() are all O(1). It's implemented as

HashSet<T> for unique value collections

HashSet&lt;T&gt; stores unique values with O(1) average-case membership tests. It's backed by a HashMap&lt;T, ()&gt;. I use it for deduplication, membership checks, and set operations (.union(), .intersection()). Common methods: .insert(v) adds, .cont

HashMap<K, V> for key-value lookups

HashMap&lt;K, V&gt; provides O(1) average-case lookups, inserts, and deletes. Keys must implement Hash + Eq. I use it for caches, indexing, and associative data. Common methods: .insert(k, v) adds/updates, .get(&amp;k) returns Option&lt;&amp;V&gt;, .r

Vec<T> for growable arrays with owned data

Vec&lt;T&gt; is Rust's dynamic array, stored on the heap. It grows as needed, amortizing allocations. I use Vec for collections of owned data, return values, and when you don't know the size upfront. Common methods: .push() appends, .pop() removes the

Default trait for sensible zero values

The Default trait provides a default value for a type, useful for builder patterns, config merging, and initialization. I derive Default on structs where zero/empty is meaningful. For custom logic, implement it manually. Default::default() is the stan

Drop trait for custom cleanup logic

The Drop trait runs when a value goes out of scope, similar to destructors in C++. I implement Drop for resource handles: closing file descriptors, releasing locks, or logging cleanup. The drop method takes &amp;mut self and can't fail (no Result). Ru

From and Into for type conversions

The From and Into traits provide a standard way to convert between types. Implementing From&lt;T&gt; for your type automatically provides Into&lt;T&gt; 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&lt;T&gt; 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