reactive_graph_std_numeric/behaviour/entity/operation/
behaviour_i64.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_numeric_model::NumericOperationProperties::LHS;
11use reactive_graph_std_result_model::ResultNumberI64Properties::RESULT;
12
13use crate::behaviour::as_i64;
14use crate::behaviour::entity::operation::function::NumericOperationI64Function;
15
16entity_behaviour!(
17    NumericOperationI64,
18    NumericOperationI64Factory,
19    NumericOperationI64Fsm,
20    NumericOperationI64BehaviourTransitions,
21    NumericOperationI64Validator,
22    f,
23    NumericOperationI64Function
24);
25
26behaviour_validator!(NumericOperationI64Validator, Uuid, ReactiveEntity, LHS.as_ref(), RESULT.as_ref());
27
28impl BehaviourInit<Uuid, ReactiveEntity> for NumericOperationI64BehaviourTransitions {
29    fn init(&self) -> Result<(), BehaviourInitializationFailed> {
30        let lhs = self.reactive_instance.get(LHS).and_then(as_i64).ok_or(BehaviourInitializationFailed {})?;
31        let f = self.f;
32        let initial_value = f(lhs);
33        self.reactive_instance.set(RESULT, json!(initial_value));
34        Ok(())
35    }
36}
37
38impl BehaviourConnect<Uuid, ReactiveEntity> for NumericOperationI64BehaviourTransitions {
39    fn connect(&self) -> Result<(), BehaviourConnectFailed> {
40        let reactive_instance = self.property_observers.reactive_instance.clone();
41        let f = self.f;
42        self.property_observers.observe_with_handle(LHS.as_ref(), move |v: &Value| {
43            if let Some(v) = as_i64(v.clone()) {
44                reactive_instance.set(RESULT, json!(f(v)));
45            }
46        });
47        Ok(())
48    }
49}
50
51impl BehaviourShutdown<Uuid, ReactiveEntity> for NumericOperationI64BehaviourTransitions {}
52impl BehaviourTransitions<Uuid, ReactiveEntity> for NumericOperationI64BehaviourTransitions {}
53
54#[cfg(test)]
55mod tests {
56    use std::sync::Arc;
57
58    use reactive_graph_std_numeric_model::NumericOperationI64;
59
60    use crate::behaviour::entity::operation::behaviour_i64::NumericOperationI64Factory;
61    use crate::behaviour::entity::operation::function::*;
62    use crate::behaviour::entity::operation::tests::numeric_operation;
63
64    use super::*;
65
66    #[test]
67    fn numeric_operation_behaviour_test() {
68        let nv: i64 = -1;
69        let nz: i64 = -0;
70        let pz: i64 = 0;
71        let pv: i64 = 1;
72
73        for (behaviour_ty, f) in NUMERIC_OPERATIONS_I64.iter() {
74            let entity_ty = EntityTypeId::new_from_type(behaviour_ty.namespace(), behaviour_ty.type_name());
75
76            // negative
77            let expected = f(nv);
78            let result = test_numeric_operation_behaviour(behaviour_ty, &entity_ty, nv);
79            println!("{}({})  |  {:?}  |  {:?}", entity_ty, nv, expected, result);
80            assert_eq!(expected, result.unwrap());
81
82            // negative zero
83            let expected = f(nz);
84            let result = test_numeric_operation_behaviour(behaviour_ty, &entity_ty, nz);
85            println!("{}({})  |  {:?}  |  {:?}", entity_ty, nz, expected, result);
86            assert_eq!(expected, result.unwrap());
87
88            // positive zero
89            let expected = f(pz);
90            let result = test_numeric_operation_behaviour(behaviour_ty, &entity_ty, pz);
91            println!("{}({})  |  {:?}  |  {:?}", entity_ty, pz, expected, result);
92            assert_eq!(expected, result.unwrap());
93
94            // positive
95            let expected = f(pv);
96            let result = test_numeric_operation_behaviour(behaviour_ty, &entity_ty, pv);
97            println!("{}({})  |  {:?}  |  {:?}", entity_ty, pv, expected, result);
98            assert_eq!(expected, result.unwrap());
99        }
100    }
101
102    fn test_numeric_operation_behaviour(behaviour_ty: &BehaviourTypeId, entity_ty: &EntityTypeId, v: i64) -> Option<i64> {
103        let behaviour = create_numeric_operation_behaviour(behaviour_ty, entity_ty);
104        let reactive_instance = behaviour.get_reactive_instance();
105        let numeric_operation = NumericOperationI64::from(reactive_instance.clone());
106        numeric_operation.lhs(v);
107        numeric_operation.result()
108    }
109
110    fn create_numeric_operation_behaviour(
111        behaviour_ty: &BehaviourTypeId,
112        entity_ty: &EntityTypeId,
113    ) -> Arc<dyn BehaviourFsm<Uuid, ReactiveEntity> + Send + Sync> {
114        let reactive_instance = numeric_operation(entity_ty);
115        let not_function = NUMERIC_OPERATIONS_I64.get(&behaviour_ty).expect("Failed to get function");
116        let not_factory = NumericOperationI64Factory::new(behaviour_ty.clone(), not_function.clone());
117        not_factory.create(reactive_instance.clone()).expect("Failed to create behaviour")
118    }
119}