53 lines
1.5 KiB
Rust
53 lines
1.5 KiB
Rust
/// This trait allows a `Model` to be validated.
|
|
pub trait Validate {
|
|
/// Validate the `Model`
|
|
fn validate(&self) -> impl std::future::Future<Output = Result<(), String>> + Send;
|
|
}
|
|
|
|
/// Validate a value and return an Error if validation fails.
|
|
#[macro_export]
|
|
macro_rules! validate {
|
|
($val:expr) => {
|
|
if let Err(err) = $val.validate().await {
|
|
return Err(format!("{}: {}", stringify!($val), err));
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! count_items {
|
|
// Base case: single item
|
|
($single:ident) => { 1 };
|
|
// Recursive case: count each item
|
|
($head:ident, $($tail:ident),*) => {
|
|
1 + mongod::count_items!($($tail),*)
|
|
};
|
|
}
|
|
|
|
/// This macro checks for the type of a reference and is useful for validation.
|
|
/// It will check all supplied types and return `false` if none are matching.
|
|
///
|
|
/// # Example
|
|
/// ```ignore
|
|
/// fn validate(&self) -> bool {
|
|
/// assert_reference_of!(self.owner, Person);
|
|
/// true
|
|
/// }
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! assert_reference_of {
|
|
($var:expr, $($struct_name:ident),+) => {
|
|
let mut match_found = false;
|
|
$(
|
|
if $var.is_of_collection($struct_name::collection_name()) {
|
|
match_found = true;
|
|
}
|
|
)*
|
|
if !match_found {
|
|
let possible_types: [&str; mongod::count_items!($($struct_name),*)] = [
|
|
$(stringify!($struct_name)),*
|
|
];
|
|
return Err(format!("{} is not of any type: {:?}", stringify!($var), possible_types));
|
|
}
|
|
};
|
|
}
|