reactive_graph_std_arithmetic/behaviour/entity/gate/
function.rs

1use std::sync::Arc;
2use std::sync::LazyLock;
3
4use reactive_graph_behaviour_model_impl::entity::EntityBehaviourFactoryCreator;
5use reactive_graph_behaviour_model_impl::entity::EntityBehaviourFunctions;
6use reactive_graph_behaviour_model_impl::entity::EntityBehaviourFunctionsStorage;
7
8use reactive_graph_std_arithmetic_model::NAMESPACE_ARITHMETIC_F64;
9use reactive_graph_std_arithmetic_model::NAMESPACE_ARITHMETIC_I64;
10use reactive_graph_std_arithmetic_model::NAMESPACE_ARITHMETIC_U64;
11
12use crate::behaviour::entity::gate::behaviour_f64::ArithmeticGateF64Factory;
13use crate::behaviour::entity::gate::behaviour_i64::ArithmeticGateI64Factory;
14use crate::behaviour::entity::gate::behaviour_u64::ArithmeticGateU64Factory;
15
16pub type ArithmeticGateFunction<T> = fn(T, T) -> T;
17pub type ArithmeticGateF64Function = ArithmeticGateFunction<f64>;
18pub type ArithmeticGateI64Function = ArithmeticGateFunction<i64>;
19pub type ArithmeticGateU64Function = ArithmeticGateFunction<u64>;
20
21pub const FN_ADD_F64: ArithmeticGateF64Function = |lhs, rhs| lhs + rhs;
22pub const FN_DIV_F64: ArithmeticGateF64Function = |lhs, rhs| if rhs != 0.0 { lhs / rhs } else { 0.0 };
23pub const FN_MAX_F64: ArithmeticGateF64Function = |lhs, rhs| lhs.max(rhs);
24pub const FN_MIN_F64: ArithmeticGateF64Function = |lhs, rhs| lhs.min(rhs);
25pub const FN_MOD_F64: ArithmeticGateF64Function = |lhs, rhs| if rhs != 0.0 { lhs % rhs } else { 0.0 };
26pub const FN_MUL_F64: ArithmeticGateF64Function = |lhs, rhs| lhs * rhs;
27pub const FN_SUB_F64: ArithmeticGateF64Function = |lhs, rhs| lhs - rhs;
28
29pub const FN_ADD_I64: ArithmeticGateI64Function = |lhs, rhs| lhs + rhs;
30pub const FN_DIV_I64: ArithmeticGateI64Function = |lhs, rhs| if rhs != 0 { lhs / rhs } else { 0 };
31pub const FN_MAX_I64: ArithmeticGateI64Function = |lhs, rhs| lhs.max(rhs);
32pub const FN_MIN_I64: ArithmeticGateI64Function = |lhs, rhs| lhs.min(rhs);
33pub const FN_MOD_I64: ArithmeticGateI64Function = |lhs, rhs| if rhs != 0 { lhs % rhs } else { 0 };
34pub const FN_MUL_I64: ArithmeticGateI64Function = |lhs, rhs| lhs * rhs;
35pub const FN_SUB_I64: ArithmeticGateI64Function = |lhs, rhs| lhs - rhs;
36
37pub const FN_ADD_U64: ArithmeticGateU64Function = |lhs, rhs| lhs + rhs;
38pub const FN_DIV_U64: ArithmeticGateU64Function = |lhs, rhs| if rhs != 0 { lhs / rhs } else { 0 };
39pub const FN_MAX_U64: ArithmeticGateU64Function = |lhs, rhs| lhs.max(rhs);
40pub const FN_MIN_U64: ArithmeticGateU64Function = |lhs, rhs| lhs.min(rhs);
41pub const FN_MOD_U64: ArithmeticGateU64Function = |lhs, rhs| if rhs != 0 { lhs % rhs } else { 0 };
42pub const FN_MUL_U64: ArithmeticGateU64Function = |lhs, rhs| lhs * rhs;
43pub const FN_SUB_U64: ArithmeticGateU64Function = |lhs, rhs| lhs - rhs;
44
45const FACTORY_CREATOR_F64: EntityBehaviourFactoryCreator<ArithmeticGateF64Function> = |ty, f| Arc::new(ArithmeticGateF64Factory::new(ty.clone(), f));
46const FACTORY_CREATOR_I64: EntityBehaviourFactoryCreator<ArithmeticGateI64Function> = |ty, f| Arc::new(ArithmeticGateI64Factory::new(ty.clone(), f));
47const FACTORY_CREATOR_U64: EntityBehaviourFactoryCreator<ArithmeticGateU64Function> = |ty, f| Arc::new(ArithmeticGateU64Factory::new(ty.clone(), f));
48
49pub static ARITHMETIC_GATES_F64: EntityBehaviourFunctionsStorage<ArithmeticGateF64Function> = LazyLock::new(|| {
50    EntityBehaviourFunctions::<ArithmeticGateF64Function>::with_namespace(NAMESPACE_ARITHMETIC_F64, FACTORY_CREATOR_F64)
51        .behaviour("add", FN_ADD_F64)
52        .behaviour("div", FN_DIV_F64)
53        .behaviour("max", FN_MAX_F64)
54        .behaviour("min", FN_MIN_F64)
55        .behaviour("mod", FN_MOD_F64)
56        .behaviour("mul", FN_MUL_F64)
57        .behaviour("sub", FN_SUB_F64)
58        .get()
59});
60
61pub static ARITHMETIC_GATES_I64: EntityBehaviourFunctionsStorage<ArithmeticGateI64Function> = LazyLock::new(|| {
62    EntityBehaviourFunctions::<ArithmeticGateI64Function>::with_namespace(NAMESPACE_ARITHMETIC_I64, FACTORY_CREATOR_I64)
63        .behaviour("add", FN_ADD_I64)
64        .behaviour("div", FN_DIV_I64)
65        .behaviour("max", FN_MAX_I64)
66        .behaviour("min", FN_MIN_I64)
67        .behaviour("mod", FN_MOD_I64)
68        .behaviour("mul", FN_MUL_I64)
69        .behaviour("sub", FN_SUB_I64)
70        .get()
71});
72
73pub static ARITHMETIC_GATES_U64: EntityBehaviourFunctionsStorage<ArithmeticGateU64Function> = LazyLock::new(|| {
74    EntityBehaviourFunctions::<ArithmeticGateU64Function>::with_namespace(NAMESPACE_ARITHMETIC_U64, FACTORY_CREATOR_U64)
75        .behaviour("add", FN_ADD_U64)
76        .behaviour("div", FN_DIV_U64)
77        .behaviour("max", FN_MAX_U64)
78        .behaviour("min", FN_MIN_U64)
79        .behaviour("mod", FN_MOD_U64)
80        .behaviour("mul", FN_MUL_U64)
81        .behaviour("sub", FN_SUB_U64)
82        .get()
83});
84
85#[cfg(test)]
86mod tests {
87
88    use super::*;
89
90    #[test]
91    fn arithmetic_gate_f64_function_test() {
92        let lhs: f64 = 0.5;
93        let rhs: f64 = 0.5;
94        assert_eq!(lhs + rhs, FN_ADD_F64(lhs, rhs));
95        assert_eq!(lhs / rhs, FN_DIV_F64(lhs, rhs));
96        assert_eq!(lhs.min(rhs), FN_MAX_F64(lhs, rhs));
97        assert_eq!(lhs.max(rhs), FN_MIN_F64(lhs, rhs));
98        assert_eq!(lhs % rhs, FN_MOD_F64(lhs, rhs));
99        assert_eq!(lhs * rhs, FN_MUL_F64(lhs, rhs));
100        assert_eq!(lhs - rhs, FN_SUB_F64(lhs, rhs));
101    }
102
103    #[test]
104    fn arithmetic_gate_i64_function_test() {
105        let lhs: i64 = -10;
106        let rhs: i64 = -10;
107        assert_eq!(lhs + rhs, FN_ADD_I64(lhs, rhs));
108        assert_eq!(lhs / rhs, FN_DIV_I64(lhs, rhs));
109        assert_eq!(lhs.min(rhs), FN_MAX_I64(lhs, rhs));
110        assert_eq!(lhs.max(rhs), FN_MIN_I64(lhs, rhs));
111        assert_eq!(lhs % rhs, FN_MOD_I64(lhs, rhs));
112        assert_eq!(lhs * rhs, FN_MUL_I64(lhs, rhs));
113        assert_eq!(lhs - rhs, FN_SUB_I64(lhs, rhs));
114    }
115
116    #[test]
117    fn arithmetic_gate_u64_function_test() {
118        let lhs: u64 = 10;
119        let rhs: u64 = 10;
120        assert_eq!(lhs + rhs, FN_ADD_U64(lhs, rhs));
121        assert_eq!(lhs / rhs, FN_DIV_U64(lhs, rhs));
122        assert_eq!(lhs.min(rhs), FN_MAX_U64(lhs, rhs));
123        assert_eq!(lhs.max(rhs), FN_MIN_U64(lhs, rhs));
124        assert_eq!(lhs % rhs, FN_MOD_U64(lhs, rhs));
125        assert_eq!(lhs * rhs, FN_MUL_U64(lhs, rhs));
126        assert_eq!(lhs - rhs, FN_SUB_U64(lhs, rhs));
127    }
128}