#Rust

22 posts

Working with JSON in Rust: A Practical serde Deserialization Guide
4 min read

Working with JSON in Rust: A Practical serde Deserialization Guide

serde, Rust's standard for JSON, organized in working order: struct deserialization starting from one derive line, Option and default for real-world JSON with missing fields, rename_all to bridge camelCase APIs, feeling out unknown JSON with Value, enums with tag and untagged for responses that come in several shapes, and reading positions out of error messages.

Building Python Extension Modules with PyO3: From maturin Build to Wheel Publishing
4 min read

Building Python Extension Modules with PyO3: From maturin Build to Wheel Publishing

Walking the path Polars, Ruff, and pydantic proved: rewrite only Python's bottleneck function in Rust. The project structure maturin new creates, exposing Rust functions to Python with #[pyfunction] and #[pymodule], the maturin develop cycle, the type conversion rules (str, list, dict), the fit with free-threaded Python, and wheel builds through PyPI publishing.

Box vs Rc vs Arc: Rust Smart Pointers and When to Use Which
4 min read

Box vs Rc vs Arc: Rust Smart Pointers and When to Use Which

Collecting the IOU the basics course left to The Book. The three situations that need Box (recursive types, dyn traits, moving large values), Rc and reference counting for multiple owners, Arc for crossing threads, RefCell and interior mutability with runtime borrow checking, and the working idioms Rc<RefCell<T>> and Arc<Mutex<T>> — with the selection criteria as a decision sequence.

Rust vs Go: How to Choose for Servers, CLIs, and Systems Programming
4 min read

Rust vs Go: How to Choose for Servers, CLIs, and Systems Programming

Both are statically typed, compiled languages producing single binaries — yet their design philosophies are close to opposites. Memory management (GC vs ownership), concurrency (built-in goroutines vs the async ecosystem), learning curve and team onboarding, latency characteristics, and which side wins for web APIs, CLI tools, infrastructure software, and embedded — the decision criteria, organized.

Rust Borrow Checker Errors, Solved: value moved, cannot borrow, does not live long enough
5 min read

Rust Borrow Checker Errors, Solved: value moved, cannot borrow, does not live long enough

The borrow checker errors Rust beginners meet most often, organized by error code: E0382 (use after move), E0502 (immutable/mutable borrow conflict), E0499 (two mutable borrows), E0506 (assigning to a borrowed value), E0597 (does not live long enough), and E0596 (closure capture) — each with its cause and standard fixes, in diagnose → cause → solution order.

Rust in Practice #8 Distribution: Publishing to crates.io and Automating GitHub Releases
4 min read

Rust in Practice #8 Distribution: Publishing to crates.io and Automating GitHub Releases

The final part of the practice course. The metadata crates.io requires and the cargo publish procedure (dry-run, the permanence of published versions, yank), the one-line cargo install experience, GitHub Releases binaries for users without Rust, and the GitHub Actions matrix workflow that builds and uploads on three operating systems when a tag is pushed — then the series wrap-up.

Rust in Practice #7 Release Optimization and Cross-Compilation: Small, Fast Binaries That Run Anywhere
4 min read

Rust in Practice #7 Release Optimization and Cross-Compilation: Small, Fast Binaries That Run Anywhere

The first half of shipping. Tightening [profile.release] (lto, codegen-units, strip) and what each option trades away, why panic = "abort" should not be flipped casually, how binary size shrinks, and cross-compilation with rustup target — especially the musl static-link build that removes the glibc dependency and runs on old servers, plus the cross tool that detours linker problems through Docker.

Rust in Practice #6 Testing: From Parser Unit Tests to CLI Integration Tests
4 min read

Rust in Practice #6 Testing: From Parser Unit Tests to CLI Integration Tests

Wrapping loglens in a safety net. #[cfg(test)] unit tests living next to the code (the parser's normal, boundary, and failure cases), integration tests in the tests/ directory, CLI tests that run the built binary and verify output and exit codes with assert_cmd and predicates, temporary log files via tempfile, and what it means that cargo test runs tests in parallel.

Rust in Practice #5 Parallelism with rayon: Map-Reduce Without Data Races
4 min read

Rust in Practice #5 Parallelism with rayon: Map-Reduce Without Data Races

Spreading the aggregation across cores. When parallelism pays off (CPU-bound work) and why the strategy switches from streaming to whole-file reads, per-thread partial aggregates with rayon's par_lines plus fold and reduce, why sharing one HashMap behind a Mutex gets slower (lock contention), and the moment the compiler catches a shared-mutable-state mistake.

Rust in Practice #4 Iterators at Work: Aggregation, Top-N, and the Release Build Difference
4 min read

Rust in Practice #4 Iterators at Work: Aggregation, Top-N, and the Release Build Difference

Stacking analysis on the parser: an aggregation structure that counts failures while streaming successes, status code distribution via HashMap entry, top-N by sorting, the completion of the stats and top commands, and measuring debug vs release with Instant — why the gap runs to dozens of times, and why release is not the default.

Rust in Practice #3 File IO and Parsing: Read with BufReader, Turn a Log Line into a Struct
5 min read

Rust in Practice #3 File IO and Parsing: Read with BufReader, Turn a Log Line into a Struct

Two fundamentals for handling large files: choosing between read_to_string (whole file in memory) and BufReader streaming, and how buffering relates to system calls. Then the parser that turns an access-log line into a LogEntry struct — quote handling, status code conversion, Part 2's ParseError in action — and the serde extension that accepts JSON Lines logs.

Rust in Practice #2 Error Design: anyhow and thiserror, Engineering How It Dies
4 min read

Rust in Practice #2 Error Design: anyhow and thiserror, Engineering How It Dies

In a CLI tool, error messages are part of the user interface. The division of labor between anyhow — the default for the application layer, with main returning anyhow::Result and context stacking up the story — and thiserror, which builds concrete error types callers can branch on. The criterion for choosing between them, plus exit codes: designing every error path in loglens.