type-lib 1.0.0

Validation and type constraint library. Declare domain types with invariants enforced at construction. Parse-dont-validate pattern as a first-class citizen. Zero-overhead wrappers with derive macros.
Documentation
# type-lib v0.2.0 — Foundation

**The public API surface that 1.0 will preserve.** v0.2.0 turns the scaffold into
a working parse-dont-validate library built on two composable pieces — the
`Validator` trait and the `Refined<T, V>` wrapper — plus a ready-made
`ValidationError`, a `prelude`, full rustdoc with examples on every item, and an
end-to-end integration suite. Zero runtime overhead: `Refined` is
`#[repr(transparent)]` over its value. The only public item carried over from
v0.1.0, `VERSION`, is unchanged.

## What is type-lib?

A validation and type-constraint library for Rust. You declare domain types whose
invariants are enforced at construction and proven by the type system thereafter,
so code that receives a validated value never re-checks it. Wrappers are
zero-overhead, the core is `no_std`-friendly, and rules are reusable across value
types.

## What's new in 0.2.0

### `Validator` — reusable, type-level rules

A `Validator<T>` is a validation rule implemented on a zero-sized marker type and
selected through the type system. It carries no state and is never instantiated.
The single `validate` method is a pure predicate over a borrowed value.

```rust
use type_lib::{ValidationError, Validator};

struct NonEmpty;

impl<S: AsRef<str> + ?Sized> Validator<S> for NonEmpty {
    type Error = ValidationError;

    fn validate(value: &S) -> Result<(), Self::Error> {
        if value.as_ref().is_empty() {
            Err(ValidationError::new("non_empty", "value must not be empty"))
        } else {
            Ok(())
        }
    }
}
```

Because `T` is `?Sized` and rules can be written over a borrow (`S: AsRef<str>`),
a single marker type validates `&str`, `String`, and `str` alike. The associated
`Error` type means a rule can return either the bundled `ValidationError` or any
bespoke, structured error.

### `Refined<T, V>` — the zero-cost validated wrapper

`Refined<T, V>` holds a `T` proven to satisfy `V`. It is constructed only by
validating once, through `Refined::new`, and the type proves the invariant from
then on.

```rust
use type_lib::{Refined, ValidationError, Validator};
# struct NonEmpty;
# impl<S: AsRef<str> + ?Sized> Validator<S> for NonEmpty {
#     type Error = ValidationError;
#     fn validate(v: &S) -> Result<(), Self::Error> {
#         if v.as_ref().is_empty() { Err(ValidationError::new("non_empty", "empty")) } else { Ok(()) }
#     }
# }

type Username = Refined<String, NonEmpty>;

let user = Username::new("alice".to_owned());   // Ok(_)
assert!(user.is_ok());
assert!(Username::new(String::new()).is_err()); // rejected
```

It is `#[repr(transparent)]` over `T` — same size, same alignment — so the
guarantee costs nothing at runtime. There is deliberately **no `DerefMut`, no
public field, and no unchecked constructor**: a validated value cannot be mutated
into an invalid one behind the type's back. Reading is via `Deref`, `get`, or
`into_inner`; `Refined` delegates `Clone`/`Copy`/`Debug`/`Display`/`PartialEq`/
`Eq`/`PartialOrd`/`Ord`/`Hash` to the inner value, bounded on `T` rather than the
marker `V`, so it slots into collections and comparisons unchanged. Cloning never
re-validates.

### `ValidationError` — a ready-made error

`ValidationError` is the default failure type for simple rules: a stable,
machine-readable `code` plus a human-readable `message`. It is `Copy`, allocates
nothing, has a `const` constructor, and works under `no_std`. Under the `std`
feature it implements `std::error::Error`.

```rust
use type_lib::ValidationError;

const EMPTY: ValidationError = ValidationError::new("non_empty", "value must not be empty");
assert_eq!(EMPTY.code(), "non_empty");
assert_eq!(EMPTY.to_string(), "non_empty: value must not be empty");
```

### `prelude` and documentation

A `prelude` module re-exports `Refined`, `Validator`, and `ValidationError`. Every
public item has rustdoc with at least one runnable example, and `docs/API.md` now
documents the full surface — each item with its parameters, return values, error
semantics, and multiple examples — alongside a Patterns section (domain-type
aliasing, cross-borrow rules, structured errors, updating a refined value).

### Tests

Unit tests live beside each item; `tests/foundation.rs` exercises the public API
end to end the way a downstream crate would — defining rules, wrapping values,
using refined values as map keys, and round-tripping through `into_inner`.

## Breaking changes

**None** relative to v0.1.0. `VERSION` is unchanged; everything else in v0.2.0 is
purely additive.

## Verification

Run on Windows x86_64 (Rust stable 1.95 and MSRV 1.75.0) and on Linux (WSL2
Ubuntu); identical commands pass via the CI matrix (Linux/macOS/Windows ×
{stable, 1.75.0}):

```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo clippy --all-targets --no-default-features -- -D warnings
cargo test --all-features
cargo test --no-default-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
```

All green. Counts at this tag (identical with and without default features):

- 12 unit tests
- 6 integration tests (`foundation.rs` + `smoke.rs`)
- 17 doctests

## What's next

- **v0.5.0 — Implementation.** Built-in rule sets (length, range, pattern,
  character class, …), rule composition, and a derive macro for generating
  validated newtypes; property tests and benchmarks.

## Installation

```toml
[dependencies]
type-lib = "0.2.0"

# no_std build
type-lib = { version = "0.2.0", default-features = false }
```

MSRV: Rust 1.75.

## Documentation

- [README]https://github.com/jamesgober/type-lib/blob/main/README.md
- [API Reference]https://github.com/jamesgober/type-lib/blob/main/docs/API.md
- [CHANGELOG]https://github.com/jamesgober/type-lib/blob/main/CHANGELOG.md

---

**Full diff:** [`v0.1.0...v0.2.0`](https://github.com/jamesgober/type-lib/compare/v0.1.0...v0.2.0).
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/type-lib/blob/main/CHANGELOG.md#020---2026-05-27).