|
4 | 4 | */ |
5 | 5 |
|
6 | 6 | //! |
7 | | -//! Trait for model verification. |
| 7 | +//! Trait for assumption verification used in the Model type. |
8 | 8 | //! |
9 | | -use crate::{AssumptionError, PropagatingEffect}; |
| 9 | +use crate::{Assumable, Assumption, AssumptionError, PropagatingEffect}; |
| 10 | +use std::sync::Arc; |
10 | 11 |
|
11 | 12 | pub trait Transferable { |
| 13 | + fn get_assumptions(&self) -> &Option<Arc<Vec<Assumption>>>; |
| 14 | + |
12 | 15 | /// Verifies the model's assumptions against a given PropagatingEffect. |
13 | 16 | /// |
| 17 | + /// The function iterates through all defined assumptions and checks them against |
| 18 | + /// the provided data. It short-circuits and returns immediately on the first |
| 19 | + /// failure or error. |
| 20 | + /// |
| 21 | + /// Overwrite the default implementation if you need customization. |
| 22 | + /// |
14 | 23 | /// # Arguments |
15 | | - /// * `effect` - The output of a model run or sample data to be tested. |
| 24 | + /// * `effect` - Sample data to be tested. Details on sampling should be documented in each assumption. |
16 | 25 | /// |
17 | 26 | /// # Returns |
18 | | - /// * `Ok(true)` if all assumptions hold true. |
19 | | - /// * `Ok(false)` if any assumption fails evaluation. |
20 | | - /// * `Err(AssumptionError)` if the model has no assumptions or an evaluation error occurs. |
21 | | - fn verify_assumptions(&self, effect: &[PropagatingEffect]) -> Result<bool, AssumptionError>; |
| 27 | + /// * `Ok(())` if all assumptions hold true. |
| 28 | + /// * `Err(AssumptionError::AssumptionFailed(String))` if an assumption is not met. |
| 29 | + /// * `Err(AssumptionError::NoAssumptionsDefined)` if the model has no assumptions. |
| 30 | + /// * `Err(AssumptionError::NoDataToTestDefined)` if the effect slice is empty. |
| 31 | + /// * `Err(AssumptionError::EvaluationError(...))` if an error occurs during evaluation. |
| 32 | + /// |
| 33 | + fn verify_assumptions(&self, effect: &[PropagatingEffect]) -> Result<(), AssumptionError> { |
| 34 | + if effect.is_empty() { |
| 35 | + return Err(AssumptionError::NoDataToTestDefined); |
| 36 | + } |
| 37 | + |
| 38 | + if self.get_assumptions().is_none() { |
| 39 | + return Err(AssumptionError::NoAssumptionsDefined); |
| 40 | + } |
| 41 | + |
| 42 | + let assumptions = self.get_assumptions().as_ref().unwrap(); |
| 43 | + |
| 44 | + for assumption in assumptions.iter() { |
| 45 | + // The `?` operator propagates any evaluation errors. |
| 46 | + if !assumption.verify_assumption(effect)? { |
| 47 | + // If an assumption returns `Ok(false)`, the check has failed. |
| 48 | + // We now return an error containing the specific assumption that failed. |
| 49 | + return Err(AssumptionError::AssumptionFailed(assumption.to_string())); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + // If the loop completes, all assumptions passed. |
| 54 | + Ok(()) |
| 55 | + } |
22 | 56 | } |
0 commit comments