reactive_graph_std_arithmetic/behaviour/entity/operation/
behaviour_f64.rs

1use reactive_graph_behaviour_model_api::behaviour_validator;
2use reactive_graph_behaviour_model_api::prelude::*;
3use reactive_graph_behaviour_model_impl::entity_behaviour;
4use reactive_graph_graph::prelude::*;
5use reactive_graph_reactive_model_impl::ReactiveEntity;
6use serde_json::Value;
7use serde_json::json;
8use uuid::Uuid;
9
10use reactive_graph_std_arithmetic_model::ArithmeticOperationProperties::LHS;
11use reactive_graph_std_arithmetic_model::ArithmeticOperationProperties::RESULT;
12
13use crate::behaviour::as_f64;
14use crate::behaviour::entity::operation::function::ArithmeticOperationF64Function;
15
16entity_behaviour!(
17    ArithmeticOperationF64,
18    ArithmeticOperationF64Factory,
19    ArithmeticOperationF64Fsm,
20    ArithmeticOperationF64BehaviourTransitions,
21    ArithmeticOperationF64Validator,
22    f,
23    ArithmeticOperationF64Function
24);
25
26behaviour_validator!(ArithmeticOperationF64Validator, Uuid, ReactiveEntity, LHS.as_ref(), RESULT.as_ref());
27
28impl BehaviourInit<Uuid, ReactiveEntity> for ArithmeticOperationF64BehaviourTransitions {
29    fn init(&self) -> Result<(), BehaviourInitializationFailed> {
30        let lhs = self.reactive_instance.get(LHS).and_then(as_f64).ok_or(BehaviourInitializationFailed {})?;
31        let f = self.f;
32        self.reactive_instance.set(RESULT, json!(f(lhs)));
33        Ok(())
34    }
35}
36
37impl BehaviourConnect<Uuid, ReactiveEntity> for ArithmeticOperationF64BehaviourTransitions {
38    fn connect(&self) -> Result<(), BehaviourConnectFailed> {
39        let reactive_instance = self.property_observers.reactive_instance.clone();
40        let f = self.f;
41        self.property_observers.observe_with_handle(LHS.as_ref(), move |v: &Value| {
42            if let Some(v) = as_f64(v.clone()) {
43                reactive_instance.set(RESULT, json!(f(v)));
44            }
45        });
46        Ok(())
47    }
48}
49
50impl BehaviourShutdown<Uuid, ReactiveEntity> for ArithmeticOperationF64BehaviourTransitions {}
51impl BehaviourTransitions<Uuid, ReactiveEntity> for ArithmeticOperationF64BehaviourTransitions {}
52
53#[cfg(test)]
54mod tests {
55    use std::sync::Arc;
56
57    use reactive_graph_behaviour_model_api::prelude::*;
58    use reactive_graph_graph::prelude::*;
59    use reactive_graph_reactive_model_api::ReactiveInstanceContainer;
60    // use reactive_graph_reactive_api::prelude::*;
61    use reactive_graph_reactive_model_impl::ReactiveEntity;
62    use reactive_graph_reactive_model_impl::ReactiveProperties;
63    use serde_json::json;
64    use uuid::Uuid;
65
66    use reactive_graph_std_arithmetic_model::ArithmeticOperationProperties;
67    use reactive_graph_std_arithmetic_model::NAMESPACE_ARITHMETIC_F64;
68
69    use crate::behaviour::entity::operation::behaviour_f64::ArithmeticOperationF64;
70    use crate::behaviour::entity::operation::function::*;
71
72    const LHS: ArithmeticOperationProperties = ArithmeticOperationProperties::LHS;
73    const RESULT: ArithmeticOperationProperties = ArithmeticOperationProperties::RESULT;
74
75    #[test]
76    fn arithmetic_operation_behaviour_test() {
77        let lhs: f64 = -10.0;
78        let incremented_value = test_arithmetic_operation_behaviour("increment", FN_INCREMENT_F64, lhs);
79        assert_eq!(-9.0, incremented_value);
80        let decremented_value = test_arithmetic_operation_behaviour("decrement", FN_DECREMENT_F64, lhs);
81        assert_eq!(-11.0, decremented_value);
82    }
83
84    fn test_arithmetic_operation_behaviour(type_name: &str, f: ArithmeticOperationFunction<f64>, v: f64) -> f64 {
85        let ty = EntityTypeId::new_from_type(NAMESPACE_ARITHMETIC_F64, type_name);
86        let behaviour = create_arithmetic_operation_behaviour(ty, f);
87        let reactive_instance = behaviour.get_reactive_instance();
88        let arithmetic_operation = reactive_graph_std_arithmetic_model::ArithmeticOperationF64::from(reactive_instance.clone());
89        arithmetic_operation.lhs(v);
90        arithmetic_operation.result().expect("Result is not of type f64")
91    }
92
93    fn create_arithmetic_operation_behaviour(ty: EntityTypeId, f: ArithmeticOperationFunction<f64>) -> Arc<ArithmeticOperationF64> {
94        let behaviour_ty = BehaviourTypeId::from(NamespacedType::from(&ty));
95        let reactive_instance = create_arithmetic_operation_entity(ty.clone());
96        ArithmeticOperationF64::new(reactive_instance, behaviour_ty, f).expect("Failed to create ArithmeticOperationF64")
97    }
98
99    fn create_arithmetic_operation_entity(ty: EntityTypeId) -> ReactiveEntity {
100        let id = Uuid::new_v4();
101        let properties = PropertyInstances::new().property(LHS, json!(0.0)).property(RESULT, json!(0.0));
102        ReactiveEntity::builder()
103            .ty(ty)
104            .id(id)
105            .properties(ReactiveProperties::new_with_id_from_properties(id, properties))
106            .build()
107    }
108}