pub trait Validate: Sized {
type Context: ?Sized;
type Output;
type Error;
// Required method
fn validate_in_context(
self,
ctx: &Self::Context,
) -> Result<Self::Output, Self::Error>;
// Provided method
fn validate(self) -> Result<Self::Output, Self::Error>
where Self::Context: From<()> { ... }
}Expand description
Deterministic validation.
Types implementing Validate commit to a single, canonical notion of validity, encoded
by the Output type. The implementation of Validate must ensure that all invariants
assumed of Output hold, and Output itself should not be constructible in a way that would
violate those invariants.
In other words, Output should correctly implement Valid.
§Examples
use peer_pressure::Validate;
struct RawAge(i32);
struct Age(u32);
impl Validate for RawAge {
// Age being non-negative is a context-free property
type Context = ();
type Output = Age;
type Error = &'static str;
fn validate_in_context(self, _: &()) -> Result<Age, &'static str> {
if self.0 >= 0 {
Ok(Age(self.0 as u32))
} else {
Err("negative age")
}
}
}
let age = RawAge(30).validate().unwrap();
assert_eq!(age.0, 30);
assert!(RawAge(-1).validate().is_err());use peer_pressure::Validate;
type ScrabbleHand = Vec<char>;
pub struct Word(String);
pub struct LegalWord(String);
impl Validate for Word {
// A scrabble word is valid for a given set of letters on hand
type Context = ScrabbleHand;
type Output = LegalWord;
type Error = &'static str;
fn validate_in_context(self, hand: &ScrabbleHand) -> Result<LegalWord, Self::Error> {
todo!("cmon, you can implement that yourself")
}
}Required Associated Types§
Required Methods§
Provided Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".