Archive

1046 posts · Page 76 of 88. ← Blog

Pratik Dhanave · ·8 min read

Macros

You've been using macros since your very first Rust program — `println!` is one, and so are `vec!`, `assert_eq!`, and `#[derive(...)]`. That telltale exclamation mark, and those `#[...]` attributes, mark code that isn't a normal function call but metaprogramming: code that writes code at compile time. Macros are how Rust does the powerful, boilerplate-eliminating tricks that would need runtime reflection or code generators in other languages — all checked at compile time. This closing post of the series demystifies them.

You've been using macros since your first Rust program — println! is one, and so are vec!, assert_eq!, and #[derive(...)]. That exclamation mark marks metaprogramming: code that writes code at compile time. This closing post of the series demystifies Rust's powerful, boilerplate-eliminating macro system.

Pratik Dhanave · ·8 min read

Error Handling with anyhow and thiserror

Module 1 covered Rust's error-handling foundation — `Result`, `Option`, and the `?` operator. It works, but as programs grow, two friction points appear: defining custom error types by hand is tedious boilerplate, and propagating many different error types through `?` gets awkward. The Rust ecosystem answers with two small, near-universal crates — `thiserror` and `anyhow` — that make error handling ergonomic. Knowing which to use where is a piece of practical Rust fluency every real project needs.

Module 1 covered Rust's error-handling foundation — Result, Option, and ?. As programs grow, two frictions appear: defining custom error types is tedious boilerplate, and propagating many error types through ? gets awkward. The ecosystem answers with two near-universal crates — thiserror and anyhow — and knowing which to use where is essential Rust fluency.

Pratik Dhanave · ·8 min read

Testing in Rust

Most languages treat testing as an afterthought — a separate framework you bolt on, a separate directory, a separate mental mode. Rust treats it as a first-class, built-in feature: testing is part of the language and its tooling, you write tests right next to the code they test, and `cargo test` just works. This tight integration, combined with Rust's culture of correctness, makes testing in Rust unusually pleasant and encourages a habit that pairs perfectly with the compiler's guarantees.

Most languages treat testing as an afterthought. Rust treats it as first-class and built-in: testing is part of the language and tooling, you write tests right next to the code, and cargo test just works. This tight integration makes testing in Rust unusually pleasant.

Pratik Dhanave · ·8 min read

Async and Await

Threads are great for CPU-bound parallelism, but for handling thousands of network connections — each mostly waiting — spawning a thread per connection doesn't scale (recall the C10K problem from the OS series). Async/await is Rust's answer: write code that looks sequential but doesn't block a thread while waiting, letting a handful of threads handle enormous concurrency. Rust's async is powerful and zero-cost, with one distinctive twist — you bring your own runtime to actually run the async code.

For handling thousands of connections each mostly waiting, spawning a thread per connection doesn't scale. Async/await is Rust's answer: write code that looks sequential but doesn't block a thread while waiting. Rust's async is powerful and zero-cost, with one distinctive twist — you bring your own runtime.