reactive_graph_std_numeric/behaviour/entity/operation/
behaviour_i64.rs1use 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 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 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 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 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}