non 0.1.0

Type-safe wrappers for strings with compile-time guarantees.
Documentation
![non](logo.svg)
# non


[![crates.io](https://img.shields.io/crates/v/non.svg)](https://crates.io/crates/non)
[![docs.rs](https://docs.rs/non/badge.svg)](https://docs.rs/non)
[![license](https://img.shields.io/crates/l/non.svg)](https://github.com/tejtex/non/blob/main/LICENSE)

Type-safe wrappers for strings with compile-time guarantees.

---

## Overview


`non` provides zero-cost wrapper types around `String` that encode
specific invariants at the type level, preventing invalid states at runtime.

Wrappers guarantee things like non-empty strings, ASCII-only strings, exact length, and more — all enforced when creating the wrapper.

---

## Features


- **`NonEmpty`** — ensures the string is not empty
- **`NonBlank`** — ensures the string contains at least one non-whitespace character
- **`ASCII`** — ensures the string contains only ASCII characters
- **`ExactLength<N>`** — ensures the string is exactly `N` characters long
- **`LowerCase`** — ensures the string is all lowercase
- **`UpperCase`** — ensures the string is all uppercase
- **`Trimmed`** — ensures no leading or trailing whitespace
- **`Alphanumeric`** — ensures string contains only alphanumeric characters

Supports composition of wrappers, e.g. `ASCII<NonEmpty<String>>`.

Works in `no_std` environments.

---

## Usage


Add to your `Cargo.toml`:

```toml
[dependencies]
non = "0.1"
```
###  Basic usage:


```rust
use non::{NonEmpty, NonBlank, ASCII, ExactLength};

let valid = NonEmpty::new("hello".to_string()).unwrap();
assert!(NonEmpty::new("".to_string()).is_none());

let valid = NonBlank::new("hello".to_string()).unwrap();
assert!(NonBlank::new("   ".to_string()).is_none());

let valid = ASCII::new("hello".to_string()).unwrap();
assert!(ASCII::new("cześć".to_string()).is_none());

let valid = ExactLength::<2>::new("hi".to_string()).unwrap();
assert!(ExactLength::<3>::new("hi".to_string()).is_none());
```
###  You can compose wrappers:


```rust
use non::{NonEmpty, ASCII};

let non_empty = NonEmpty::new("hello".to_string()).unwrap();
let ascii_non_empty = ASCII::new(non_empty).unwrap();

assert_eq!(ascii_non_empty.as_ref(), "hello");
```
### Deref and Conversion

All wrappers deref to the inner string, so you can use string methods:

```rust
use non::NonEmpty;

let s = NonEmpty::new("hello world".to_string()).unwrap();
assert!(s.contains("world"));
```
Convert back to String easily:
```rust
use non::NonEmpty;

let non_empty = NonEmpty::new("hello".to_string()).unwrap();
let s: String = non_empty.into();
```
### Stripping Wrappers

Use the Strip trait to remove one wrapper layer:

```rust
use non::{NonEmpty, ASCII, Strip};

let non_empty = NonEmpty::new("hello".to_string()).unwrap();
let ascii_non_empty = ASCII::new(non_empty).unwrap();

let ascii_only = ascii_non_empty.strip();
assert_eq!(ascii_only, ASCII::new("hello".to_string()).unwrap());
```
##  no_std support

Works in no_std environments with alloc enabled:

```toml
[dependencies]
non = { version = "0.1", default-features = false }
```
##  License

Licensed under MIT. See LICENSE for details.