reliakit-primitives
Type-safe primitives for constrained and reliability-oriented Rust values.
reliakit-primitives provides small owned wrapper types for values that should satisfy common constraints before they move through an application or library boundary.
The crate has no dependencies and forbids unsafe code.
The goal is not to parse every domain-specific format perfectly. The goal is to make common invariants explicit in types, keep validation close to input boundaries, and avoid passing unchecked strings and numbers through public APIs.
What This Crate Does
This crate turns common validated values into explicit Rust types.
Instead of passing unchecked String, u16, u64, or f64 values through
your code, construct a primitive once and let function signatures carry the
invariant:
use ;
let name = new?;
let contact = new?;
let port = new?;
configure_service;
This is useful at boundaries such as configuration loading, request parsing, CLI input, test fixtures, and library APIs.
When To Use It
Use this crate when a value has simple validity rules that should be checked once and then carried as a typed value:
- names and identifiers that must not be empty,
- strings with minimum or maximum character lengths,
- slugs, email addresses, HTTP URLs, or hex strings,
- percentages, ports, positive integers, or positive floats,
- byte sizes that should display consistently,
- semantic version strings,
- UUIDs in canonical format,
- human-readable durations like
1h30mor500ms.
When Not To Use It
Use a domain-specific validator, parser, serializer, or schema library when a value needs rules beyond these small general-purpose primitives.
For example, Email is a basic structural validator, not a full RFC 5321 or
deliverability checker. HttpUrl checks for an HTTP(S) scheme and a non-empty
host, but it is not a complete URL parser.
Installation
[]
= "0.4"
For no_std environments:
[]
= { = "0.4", = false, = ["alloc"] }
Examples
Non-empty strings
use NonEmptyStr;
let name = new?;
Bounded strings
use BoundedStr;
type Username = ;
let username = new?;
Numeric primitives
use ;
let limit = from_mb;
let threshold = new?;
let port = new?;
Text primitives
use ;
let slug = new?;
let email = new?;
let url = new?;
assert_eq!;
assert!;
Structured values
use ;
let version = parse?;
let request_id = parse?;
let timeout = parse?;
assert!;
assert_eq!;
assert_eq!;
SemVer implements Rust's total Ord consistently with Eq. Build metadata
is used as a final tie-breaker for ordering so BTreeSet, BTreeMap, sorting,
and binary search behave correctly. Use SemVer::cmp_precedence when you need
SemVer precedence rules that ignore build metadata.
Error handling
All fallible constructors return PrimitiveResult<T>, an alias for
Result<T, PrimitiveError>.
use ;
let err = new.unwrap_err;
assert_eq!;
assert_eq!;
Use PrimitiveErrorKind when you need stable programmatic matching without
depending on display text.
Available Types
Strings
| Type | Description |
|---|---|
NonEmptyStr |
Owned string that is not empty and not whitespace-only |
BoundedStr<MIN, MAX> |
Owned string constrained by character length |
Slug |
Lowercase alphanumeric + hyphens, URL-safe |
Email |
Basic structural email validation |
HttpUrl |
URL that must start with http:// or https:// |
HexString |
Hexadecimal characters with optional 0x/0X prefix |
Base64 |
Standard (RFC 4648) base64 with correct padding |
Base32 |
Standard (RFC 4648) base32 (A-Z, 2-7) with correct padding |
Identifier |
ASCII identifier: a letter or _, then letters, digits, or _ |
Hostname |
RFC 1123 hostname (dot-separated labels, ≤253 chars) |
Numbers
| Type | Description |
|---|---|
Percent |
Integer percentage from 0 to 100 inclusive |
PercentageF64 |
Float percentage from 0.0 to 100.0 inclusive |
Port |
TCP/UDP port from 1 to 65535 inclusive |
PositiveInt |
u64 strictly greater than zero |
PositiveFloat |
Finite f64 strictly greater than zero |
ByteSize |
Byte size value with human-readable display output |
Collections
| Type | Description |
|---|---|
NonEmptyVec<T> |
Vec<T> guaranteed to contain at least one element |
Structured Values
| Type | Description |
|---|---|
SemVer |
Semantic version (1.2.3, 2.0.0-beta.1, 1.0.0+build) |
Uuid |
UUID in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format |
MacAddress |
48-bit MAC address (aa:bb:cc:dd:ee:ff or - form), allocation-free |
HumanDuration |
Duration parsed from 1h, 30m, 45s, 500ms, or combinations |
Networking
| Type | Description |
|---|---|
Cidr |
IPv4/IPv6 network in address/prefix form with contains membership, allocation-free |
Feature Flags
| Flag | Default | Description |
|---|---|---|
std |
yes | Enables std::error::Error for PrimitiveError; implies alloc |
alloc |
no | Enables the allocation-backed owned types and collection helpers |
no_std
The crate supports no_std. Building with --no-default-features (no std,
no alloc) provides the allocation-free primitives:
- numeric:
Percent,PercentageF64,Port,PositiveInt,PositiveFloat,ByteSize, Uuid,MacAddress,Cidr, andHumanDuration(parsing andDisplaydo not allocate),- the error types (
PrimitiveError,PrimitiveErrorKind,PrimitiveResult).
Enabling alloc adds the owned, allocation-backed types: Slug, Email,
HttpUrl, HexString, Base64, Base32, Identifier, Hostname,
NonEmptyStr, BoundedStr, NonEmptyVec, and SemVer.
The default std build enables alloc for normal application use:
= { = "0.4", = false, = ["alloc"] }
Safety
This crate is #![forbid(unsafe_code)].
Minimum Supported Rust Version
Rust 1.85 and newer. No nightly features are used.
Status
Active. The crate is published for real use and follows normal Rust crate
versioning. APIs may still receive compatible refinements before a 1.0
release.
Contributing
See CONTRIBUTING.md.
License
Licensed under the MIT License.