Notes on Rust, type-driven design and patterns.
I’m Serhii Potapov, a Rust developer in Berlin and the author of nutype, whatlang, envconfig and ta-rs. Older posts cover Ruby and Linux.
2026 4 posts
-
Nutype 0.8.0 - attribute passthrough, serde customization and Decimal
Attributes for repr, sqlx or garde now reach the generated type, and validation still runs after custom serde decoding.
-
Branchless Rust: Making a Filter 4x Faster by Removing an if
Why a filter is slowest when it keeps half of random input, and what a branchless rewrite gains there and loses at 1%.
-
Nutype 0.7.0 - conditional derives with cfg_attr and more
Gate derives on any cfg predicate with cfg_attr, restrict constructor visibility, validate UTF-16 length, and use derive_unchecked, formerly derive_unsafe.
-
Kinded 0.5.0 - Generate Rust Enum Kind Types Without Boilerplate
The kind() method is now a const fn, skip_derive drops default impls like Display, and attrs adds attributes such as serde renames.
2025 3 posts
-
Nutype 0.6.2 - Deriving Arbitrary Traits with
derive_unsafeDerive any third-party trait on a newtype behind an opt-in feature flag, with the caveat that traits like DerefMut can break its invariants.
-
Alternative Blanket Implementations for a Single Rust Trait
Rust rejects overlapping blanket impls, but an associated type plus marker structs lets each type pick one of two implementations.
-
Introducing Joydb: A Tiny Embedded Database for Rust Prototypes
Keep serde models in memory behind a small CRUD API and persist them to JSON, RON or CSV, with no schema or migrations.
2024 4 posts
-
Nutype 0.5.0 - custom errors!
Plug in your own validation function and error type, and build validated newtypes with try_new() now that the fallible new() is gone.
-
Nutype 0.4.3 - generic newtypes!
Newtypes can now be generic, like NonEmpty<T> over Vec<T>, with bounds such as T: Ord when a sanitizer needs to sort.
-
Nutype 0.4.2 with Arbitrary support!
A derived Arbitrary generates only values that pass the newtype’s validation, so fuzzing and property tests always get valid inputs.
-
Index out of bounds? Not always! - A Rusty Surprise
Indexing a two-element array out of bounds is a compile error, yet the same mistake through a reference, (&arr)[5], compiles.
2023 5 posts
-
Announcing Nutype 0.4.0 Release
Nutype can now wrap any inner type such as Vec<String>, min and max become greater_or_equal and less_or_equal, and error variants get names like NotEmptyViolated.
-
Handling Rust enum variants with kinded crate
Generate DrinkKind, a data-free twin of the Drink enum, with all(), configurable Display casing and lenient FromStr from a single derive.
-
Nutype 0.3.0 released
The finite validator lets float newtypes derive Eq and Ord, and a derived Default gets a generated test that checks its value is valid.
-
Nutype 0.2.0 is out!
Validate string newtypes against a regex, inline or from a lazy_static or once_cell static, or skip all checks with new_unchecked in an unsafe block.
-
Nutype: the newtype with guarantees!
Declare sanitize and validate rules and get a checked constructor plus error type, with no way to build an invalid value in safe Rust.
2022 3 posts
-
Property-Based Testing in Rust with Arbitrary
Random vehicles generated by arbitrary and arbtest uncover a failing u32 to i32 conversion that a hand-written round-trip test missed.
-
When serde_json::to_string() fails
An internally tagged serde enum serializes as a JSON object, so using it as a HashMap key fails at runtime with ‘key must be a string’.
-
From TypeScript To ReScript
Rewriting the Inhyped.com React frontend in ReScript brought a sound type system and easy JS interop, at the cost of a small community.
2021 7 posts
-
Builder with typestate in Rust
Track required fields in the builder’s type parameters, so calling build() without an id or email fails to compile.
-
Builder pattern in Rust
A chained UserBuilder stands in for the keyword and optional arguments Rust lacks, but mandatory fields bring back positional arguments.
-
Phantom Types in Rust 👻
Share Add and Sub between Meter and Kilogram through one generic Unit<T> and PhantomData, without ever letting meters mix with kilograms.
-
UUID for better data integrity
With integer keys a user id can silently pass an admin foreign key check, while UUIDs let the database catch the mix-up.
-
Whatlang strikes back
Version 0.12.0 improves results on short texts and gets a demo site, while adding only 3.5 MB to a binary versus over 100 MB for Lingua.
-
Rust Playground At Your Fingertips
One command creates a throwaway Cargo project with the crates you name and opens nvim beside cargo watch in a tmux split.
-
Rust Knowledge Refinement
Notes from rereading The Rust Book, from why Copy and Drop exclude each other to raw identifiers.
2020 1 post
-
Hidden cost of string indexing in Ruby
Non-ASCII characters turn Ruby’s String#[] from O(1) into an O(n) scan, as benchmarks and MRI’s coderange string flag show.
2019 1 post
-
Testing Infinite Loop in Ruby
Unit test a worker built around Kernel#loop by extracting its body, then cutting the loop short with Timeout or stubbing loop in RSpec.
2018 2 posts
-
How to fix intermittent test failures
Bisect a test run to find the test that leaks state, then fix flaky tests that rely on undefined ordering or on the current time.
-
Rust 2018
A Ruby web developer’s 2018 wishlist for Rust, such as stable TryFrom, generics over constants and readable types in error messages.
2017 4 posts
-
How to run Rust tests automatically
Rerun cargo test on every save with cargo watch, or use cargo-testify to get each result as a desktop notification.
-
Announcing Crystalium organization
Six Crystal libraries, including the icr console, cossack and jwt, move to a shared GitHub organization in search of new maintainers.
-
Exposing a Rust library to C
How whatlang-ffi exposes a Rust crate to C: a cdylib build, repr(C) enums and structs, and strings passed in and out via CStr and CString.
-
Introduction to Rust whatlang library and natural language identification algorithms
Whatlang picks the script most characters belong to, then the language by matching trigram profiles as in Cavnar and Trenkle’s 1994 paper.