reactive_graph_behaviour_model_api/
validation.rs

1use reactive_graph_reactive_model_api::ReactiveInstance;
2use reactive_graph_reactive_model_api::ReactiveInstanceContainer;
3
4use crate::BehaviourInvalid;
5use crate::BehaviourPropertyInvalid;
6use crate::BehaviourTypesContainer;
7
8pub trait BehaviourValidator<ID: Clone, T: ReactiveInstance<ID> + BehaviourTypesContainer>: BehaviourPropertyValidator<ID, T> {
9    /// Validates the behaviour.
10    fn validate(&self) -> Result<(), BehaviourInvalid> {
11        self.validate_properties().map_err(BehaviourInvalid::BehaviourPropertyInvalid)
12    }
13}
14
15pub trait BehaviourPropertyValidator<ID: Clone, T: ReactiveInstance<ID> + BehaviourTypesContainer>: ReactiveInstanceContainer<ID, T> {
16    /// Validates the properties of the reactive instance.
17    fn validate_properties(&self) -> Result<(), BehaviourPropertyInvalid> {
18        Ok(())
19    }
20
21    /// Validates the property with the given name.
22    fn validate_property(&self, property_name: &str) -> Result<(), BehaviourPropertyInvalid> {
23        let reactive_property_container = self.get_reactive_instance();
24        if !reactive_property_container.has_property(property_name) {
25            return Err(BehaviourPropertyInvalid::PropertyMissing(property_name.to_owned()));
26        }
27        Ok(())
28    }
29}
30
31#[macro_export]
32macro_rules! behaviour_validator {
33    ($validator: ident, $id: ty, $reactive_instance: ty) => {
34        pub struct $validator {
35            reactive_instance: $reactive_instance,
36        }
37
38        impl $validator {
39            pub fn new(reactive_instance: $reactive_instance) -> Self {
40                $validator { reactive_instance }
41            }
42        }
43
44        impl BehaviourValidator<$id, $reactive_instance> for $validator {}
45
46        impl reactive_graph_reactive_model_api::ReactiveInstanceContainer<$id, $reactive_instance> for $validator {
47            fn get_reactive_instance(&self) -> &$reactive_instance {
48                &self.reactive_instance
49            }
50        }
51    };
52
53    ($validator: ident, $id: ty, $reactive_instance: ty $(, $property_names:expr)+) => {
54        pub struct $validator {
55            reactive_instance: $reactive_instance,
56        }
57
58        impl $validator {
59            pub fn new(reactive_instance: $reactive_instance) -> Self {
60                $validator { reactive_instance }
61            }
62        }
63
64        impl $crate::BehaviourValidator<$id, $reactive_instance> for $validator {}
65
66        impl reactive_graph_reactive_model_api::ReactiveInstanceContainer<$id, $reactive_instance> for $validator {
67            fn get_reactive_instance(&self) -> &$reactive_instance {
68                &self.reactive_instance
69            }
70        }
71
72        impl $crate::BehaviourPropertyValidator<$id, $reactive_instance> for $validator {
73            fn validate_properties(&self) -> Result<(), $crate::BehaviourPropertyInvalid> {
74                $(
75                self.validate_property($property_names)?;
76                )*
77                Ok(())
78            }
79        }
80    };
81}