This crate provides a convenient macro that allows you to generate type wrappers that promise to always uphold arbitrary invariants that you specified.
Examples
Let's create a Username type. It will be a wrapper around non-empty String:
define!;
// We can't create an invalid username.
assert!;
// But we can create a valid type!
let mut u = new.unwrap;
assert_eq!;
// We can mutate it:
assert!;
assert_eq!; // our name has changed!
// But we can't make it invalid:
assert!;
assert_eq!; // our name hasn't changed!
// Let's try this...
assert!; // looks kind of invalid though :(
As you can see, the last example treats " " as a valid username, but it's not. We
can of course do something like Username::new(s.trim()) every time, but why should
we do it ourselves? Let's automate it!
define!
let mut u = new.unwrap;
assert_eq!; // now we're talking!
// This also works for mutations:
assert!;
Now our Username trims provided value automatically.
You might noticed that prae::ValidationError is returned by default when our
construction/mutation fails. Altough it's convenient, there are situations when you might
want to return a custom error. And prae can help with this:
;
define!
assert!;