| Crates.io | non |
| lib.rs | non |
| version | 0.1.0 |
| created_at | 2025-10-07 16:57:42.144079+00 |
| updated_at | 2025-10-07 16:57:42.144079+00 |
| description | Type-safe wrappers for strings with compile-time guarantees. |
| homepage | https://github.com/tejtex/non |
| repository | https://github.com/tejtex/non |
| max_upload_size | |
| id | 1871952 |
| size | 21,257 |
Type-safe wrappers for strings with compile-time guarantees.
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.
NonEmpty — ensures the string is not emptyNonBlank — ensures the string contains at least one non-whitespace characterASCII — ensures the string contains only ASCII charactersExactLength<N> — ensures the string is exactly N characters longLowerCase — ensures the string is all lowercaseUpperCase — ensures the string is all uppercaseTrimmed — ensures no leading or trailing whitespaceAlphanumeric — ensures string contains only alphanumeric charactersSupports composition of wrappers, e.g. ASCII<NonEmpty<String>>.
Works in no_std environments.
Add to your Cargo.toml:
[dependencies]
non = "0.1"
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());
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");
All wrappers deref to the inner string, so you can use string methods:
use non::NonEmpty;
let s = NonEmpty::new("hello world".to_string()).unwrap();
assert!(s.contains("world"));
Convert back to String easily:
use non::NonEmpty;
let non_empty = NonEmpty::new("hello".to_string()).unwrap();
let s: String = non_empty.into();
Use the Strip trait to remove one wrapper layer:
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());
Works in no_std environments with alloc enabled:
[dependencies]
non = { version = "0.1", default-features = false }
Licensed under MIT. See LICENSE for details.