rust

Unit tests with #[test] and assert macros

Rust's built-in test framework is simple and powerful. Mark functions with #[test], and cargo test runs them. Use assert!, assert_eq!, and assert_ne! for assertions. Tests live alongside code in the same file, typically in a #[cfg(test)] mod tests blo

impl Trait for opaque return types

impl Trait in return position lets you return a type that implements a trait without naming it. This is useful for closures, iterators, or futures where the concrete type is complex or unnameable. The caller only knows it implements the trait. I use i

Box<T> for heap allocation and recursive types

Box&lt;T&gt; is Rust's simplest smart pointer: it allocates T on the heap and gives you ownership. When the Box goes out of scope, the heap memory is freed. I use Box when I need indirection (like recursive types), when moving large structs is expensi

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

Parking_lot for faster synchronization primitives

parking_lot provides drop-in replacements for Mutex, RwLock, and Condvar that are faster and smaller than std::sync. They use more efficient parking/unparking and don't poison on panic. I use parking_lot::Mutex in hot paths where lock contention matte

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

Ownership transfer prevents double-free and use-after-free

Rust's ownership system guarantees memory safety without garbage collection. Each value has exactly one owner, and when ownership is transferred (moved), the previous owner can't use it anymore. This prevents double-frees and use-after-free bugs at co

std::process::Command for spawning external processes

std::process::Command runs external programs and captures their output. I use it for CLI tools that wrap other commands, build scripts, or integration tests. Methods like .arg(), .env(), and .current_dir() configure the process. .output() runs and wai

Deref and DerefMut for smart pointer ergonomics

Implementing Deref lets your type automatically coerce to its target type. For example, Box&lt;T&gt; derefs to T, and String derefs to str. This enables method calls and conversions without explicit unwrapping. I implement Deref for wrapper types and

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

MaybeUninit for safe uninitialized memory

MaybeUninit&lt;T&gt; is the safe way to work with uninitialized memory. It's useful for FFI, performance-critical code, or when you need to initialize large arrays element-by-element. Unlike uninitialized variables (which are UB), MaybeUninit is expli

Build scripts (build.rs) for compile-time code generation

A build.rs file runs before compiling your crate, enabling code generation, FFI binding generation, or environment checks. I use build scripts to generate Rust code from proto files (with prost), compile C libraries, or set cfg flags based on the targ