macro_rules! extend {
{
$(#[$meta:meta])*
$vis:vis $wrapper:ident: $inner:ty;
$(adjust $adjust:expr;)?
$(ensure $ensure:expr;)?
$(validate($err:ty) $validate:expr;)?
$(plugins: [$($plugin:path),+ $(,)?];)?
} => { ... };
{
$inner:ty;
$(adjust $adjust:expr;)?
} => { ... };
{
$inner:ty;
$(adjust $adjust:expr;)?
ensure $ensure:expr;
} => { ... };
{
$inner:ty;
$(adjust $adjust:expr;)?
validate($err:ty) $validate:expr;
} => { ... };
}
Expand description
Convenience macro that creates a
Newtype
wrapper struct that implements Wrapper
and extends another Wrapper
.
The usage of the macro is identical to the define!
, so
check out it’s documentation to learn more. The only difference is the fact
that the inner type specified in the type signature must implement
Wrapper
.
The created struct will inherit the inner type of that another wrapper, and also will run that another wrapper’s adjustment and validation closures before it’s own adjustment and validation closures. For example:
use prae::Wrapper;
prae::define! {
pub Text: String;
adjust |text| *text = text.trim().to_owned();
ensure |text| !text.is_empty();
}
prae::extend! {
#[derive(Debug)]
pub Sentence: Text;
ensure |sentence: &String| {
// Note that `sentence` is a `&String`, not `&Text`!
// It's value is already trimmed and checked for emptiness.
// Now we only need to check conditions that are important
// for the new type
sentence.ends_with(&['.', '!', '?'][..])
};
}
// It works
let sentence = Sentence::new(" My sentence! ").unwrap();
assert_eq!(sentence.get(), "My sentence!");
// Doesn't pass the validation of `Text`
assert!(Sentence::new(" ").is_err());
// Doesn't pass the validation of `Sentence`
assert!(Sentence::new("Without punctuation").is_err());