humfmt
Ergonomic human-readable formatting toolkit for Rust
humfmt turns raw machine values into readable text without turning formatting
into a side quest.
It currently includes:
- compact numbers like
15320 -> 15.3K - byte sizes like
1536 -> 1.5KB - ordinals like
21 -> 21st - durations like
3661s -> 1h 1m - relative time like
90s -> 1m 30s ago - natural-language lists like
["red", "green", "blue"] -> "red, green, and blue" - locale-aware output for English, Russian, and Polish
- custom locale overrides for suffixes, separators, ordinals, duration units, and list style
- optional
chronoandtimeintegration
The goal is still the same: keep the crate small, predictable, and pleasant to reach for.
Quick Example
use Humanize;
Performance Notes
humfmt is designed to be cheap to call from hot paths:
- The formatters implement
Displayand write directly to the providedfmt::Formatter. - The formatting path avoids building intermediate heap strings.
- Allocation is an explicit choice of the caller (e.g. calling
.to_string()allocates because it must own aString). - Integer compact-number scaling uses O(1) unit selection (log10-based) rather than repeated division.
- The float compact-number path uses a small stack buffer and stays compatible with stable
no_std.
In other words: formatting itself is meant to be lightweight; if you need owned output, you can allocate it explicitly.
Customized Formatting
use Duration;
use ;
List Examples
use ;
let english = list;
assert_eq!;
let plain = list_with;
assert_eq!;
Locale Examples
use Duration;
use ;
let number = number_with;
assert_eq!;
let elapsed = duration_with;
assert_eq!;
let items = list_with;
assert_eq!;
use Duration;
use ;
let number = number_with;
assert_eq!;
assert_eq!;
let relative = ago_with;
assert_eq!;
use ;
let locale = english
.short_suffix
.separators
.list_separator
.duration_unit_fn
.ago_word;
let number = number_with;
assert_eq!;
let relative = ago_with;
assert_eq!;
Current Features
- compact number formatter
- byte-size formatter
- ordinal formatter
- duration formatter
- relative time formatter
- list formatter
- long and short units
- English, Russian, and Polish locale packs
- custom locale builder for suffix and separator overrides
- configurable list separator per locale
- custom duration-unit, list-style, and relative-time wording hooks
- optional
chronoandtimeintegration - checked
chrono/timeadapters with detailed conversion errors - doctests and integration tests
Installation
[]
= "0.5"
For no_std targets:
[]
= { = "0.5", = false }
MSRV
humfmt targets Rust 1.70 (see rust-version in Cargo.toml).
Feature Flags
std(default): enables the standard-library builddefault-features = false: builds forno_stdenglish: baseline locale included in the default feature setrussian: enables thehumfmt::locale::Russianlocale packpolish: enables thehumfmt::locale::Polishlocale packalloc: reserved compatibility flag for future alloc-gating workchrono: enables adapters forchrono::TimeDeltaandchrono::DateTimetime: enables adapters fortime::Durationandtime::OffsetDateTime
Benchmarks
This repository includes a Criterion benchmark suite.
Run:
Comparison Benchmarks (tools/benchmarks)
This repository also includes a standalone comparison benchmark harness under tools/benchmarks/.
It can generate a repo-friendly report and charts:
This produces:
BENCHMARKS.md(capability matrix + comparisons + notes)assets/benchmarks/*_dark.svg
Development Status
humfmt is still early-stage, but the formatter surface is already useful and
deliberate. The direction is to keep the crate focused while expanding locale
coverage and humanizer breadth without turning the API into a maze.
Documentation
- examples:
examples/ - tests:
tests/ - benchmarks:
cargo bench - crates.io: humfmt
- docs.rs: humfmt docs
Philosophy
This crate follows one simple rule:
Human formatting should feel stupidly easy.
No giant config ceremony. No formatting gymnastics. No “why is this so annoying?” moments.
Just:
println!;
and move on with your life.
License
MIT.