What it does
type-lib makes invalid states unrepresentable. Instead of validating a value
every time it is used, you validate it once — at construction — and carry a
type that the compiler will only let exist in a valid state. Functions that take
such a type are freed from defensive checks: the type system already did them.
The foundation is two pieces that compose:
Validator— a reusable, type-level validation rule. It lives on a zero-sized marker type and is selected through the type system, so it carries no state and no storage.Refined— a#[repr(transparent)]wrapper holding a value proven to satisfy aValidator. It has the exact size and layout of the value it wraps, so the guarantee is free at runtime.
A ready-made ValidationError covers rules that
need only a code and a message; rules that need structured failures define their
own error type through Validator::Error.
Features
- Parse, don't validate — invariants are enforced at construction and proven by the type thereafter; no re-checking at call sites.
- Zero-overhead wrappers —
Refined<T, V>is#[repr(transparent)]overTand stores nothing extra. The validated type is the same size as the raw one. - Built-in rules — ready-made validators for length
(
NonEmpty,MinLen,MaxLen,LenRange), numbers (Positive,InRange, …), and string content (Ascii,Alphanumeric,Trimmed). - Composition — combine rules at the type level with
And,Or, andNot; the result is itself a rule. - Derive macro —
#[derive(Validated)](thederivefeature) turns a newtype into a named domain type with a checked constructor. - Reusable, type-level rules — write a
Validatoronce and apply it to any value type through the type system. - Tamper-proof by construction —
Refinedexposes no&mutto its inner value and no public field, so a validated value cannot be mutated into an invalid one behind the type's back. - Bring your own error — use the bundled
ValidationErroror any custom error type via theValidator::Errorassociated type. no_stdfriendly — the core API and all borrowed-value rules work withoutstd;allocadds owned-type (String/Vec) length rules andstdadds the [std::error::Error] impl.- Cross-platform — Linux, macOS, and Windows on stable and MSRV 1.75.
Performance
Validation is the only runtime cost; the wrapper adds none. Local Criterion means
(Windows x86_64, Rust stable, cargo bench):
Refined::newwithAsciion a short&str: ~0.9 nsRefined::newwithLenRange<3, 16>on a&str: ~2.2 nsRefined::newwithInRange<0, 100>on ani32: ~2.6 nsget/Derefaccessors: sub-nanosecond (compile down to a field read)
API Overview
For the complete reference with examples, see docs/API.md.
Validator— reusable, type-level validation ruleRefined— zero-cost wrapper around a validated valueValidationError— ready-madeno_stderror- Built-in rules — length, numeric, and string rules
- Combinators —
And,Or,Not Validated—#[derive]for validated newtypes (derivefeature)prelude— convenient re-exportsVERSION— compile-time crate version
Runnable demos live in examples/: quick_start, built_in_rules,
composing_rules, custom_rule, and derive_newtype
(e.g. cargo run --example quick_start).
Installation
[]
= "1.0.0"
# with the derive macro
= { = "1.0.0", = ["derive"] }
# no_std build (core API + borrowed-value rules)
= { = "1.0.0", = false }
# no_std + owned-type rules (String / Vec)
= { = "1.0.0", = false, = ["alloc"] }
MSRV: Rust 1.75.
Quick start
use And;
use ;
use Refined;
// A username: 3–16 characters with no surrounding whitespace.
// Built once, the type guarantees the invariant everywhere it is used.
type Username = ;
Prefer a distinct named type with its own constructor? Enable the derive
feature and annotate a newtype:
use And;
use ;
use Validated;
;
let user = new;
assert!;
Need a rule the built-ins don't cover? Implement Validator
on a marker type — see the custom_rule example.
For the exhaustive API reference, see docs/API.md.
Standards
- REPS governs every decision. See REPS.md.
- MSRV: Rust 1.75.
- Edition: 2021.
- Cross-platform: Linux, macOS, Windows.
License
Dual-licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.