pub struct Refined<T, V: Validator<T>> { /* private fields */ }Expand description
A value of type T that is guaranteed to satisfy the validator V.
Refined is the heart of the parse-dont-validate pattern: a value is checked
once, when the wrapper is constructed, and the type then proves the
invariant for the rest of the value’s life. Code that receives a
Refined<T, V> never has to re-validate, because a Refined that violates
V cannot be constructed through safe code.
The wrapper is #[repr(transparent)] and stores only the value plus a
zero-sized marker, so it has the exact same size and layout as T. The
guarantee costs nothing at runtime.
There is deliberately no DerefMut and no public field: handing out a &mut T would let a caller mutate the value into an invalid state behind the
type’s back. To change a refined value, build a new one with Refined::new
(or recover the inner value with Refined::into_inner, change it, and
re-wrap it).
§Examples
Define a rule, alias a domain type, and construct it:
use type_lib::{Refined, 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(())
}
}
}
/// A username that can never be empty.
type Username = Refined<String, NonEmpty>;
let user = Username::new("alice".to_owned());
assert!(user.is_ok());
assert!(Username::new(String::new()).is_err());Read the inner value through Deref, Refined::get, or
Refined::into_inner:
let user = Username::new("alice".to_owned())?;
assert_eq!(user.len(), 5); // via Deref to String
assert_eq!(user.get(), "alice"); // borrow the inner value
assert_eq!(user.into_inner(), "alice"); // take ownership backImplementations§
Source§impl<T, V: Validator<T>> Refined<T, V>
impl<T, V: Validator<T>> Refined<T, V>
Sourcepub fn new(value: T) -> Result<Self, V::Error>
pub fn new(value: T) -> Result<Self, V::Error>
Validates value and, on success, wraps it.
This is the only safe way to construct a Refined, which is what makes
the invariant trustworthy everywhere else.
§Errors
Returns V::Error when value fails V’s rule. The
value is dropped in that case.
§Examples
let ok = Refined::<&str, NonEmpty>::new("hi");
assert!(ok.is_ok());
let bad = Refined::<&str, NonEmpty>::new("");
assert!(bad.is_err());Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consumes the wrapper and returns the inner value.
Use this when you need to mutate or transform the value: take it out,
change it, then re-wrap with Refined::new to re-establish the
guarantee.
§Examples
let n = Refined::<i32, AnyI32>::new(7).expect("always valid");
assert_eq!(n.into_inner(), 7);