/// This trait allows a `Model` to be validated. pub trait Validate { /// Validate the `Model` fn validate(&self) -> impl std::future::Future> + 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)); } }; }