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

  1. 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.

  2. 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%.

  3. 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.

  4. 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

  1. Nutype 0.6.2 - Deriving Arbitrary Traits with derive_unsafe

    Derive any third-party trait on a newtype behind an opt-in feature flag, with the caveat that traits like DerefMut can break its invariants.

  2. 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.

  3. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

  1. 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.

  2. 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’.

  3. 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

  1. 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.

  2. Builder pattern in Rust

    A chained UserBuilder stands in for the keyword and optional arguments Rust lacks, but mandatory fields bring back positional arguments.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. Rust Knowledge Refinement

    Notes from rereading The Rust Book, from why Copy and Drop exclude each other to raw identifiers.

2020 1 post

  1. 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

  1. 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

  1. 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.

  2. 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

  1. 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.

  2. Announcing Crystalium organization

    Six Crystal libraries, including the icr console, cossack and jwt, move to a shared GitHub organization in search of new maintainers.

  3. 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.

  4. 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.

2015 2 posts

2014 2 posts

2013 7 posts

2012 10 posts

2011 9 posts