reactive_graph_std_random/behaviour/entity/
random_i64_range.rs

1use std::ops::Range;
2
3use rand::Rng;
4use reactive_graph_behaviour_model_api::behaviour_validator;
5use reactive_graph_behaviour_model_api::prelude::*;
6use reactive_graph_behaviour_model_impl::entity_behaviour;
7use reactive_graph_graph::prelude::*;
8use reactive_graph_reactive_model_impl::ReactiveEntity;
9use reactive_graph_runtime_model::ActionProperties::TRIGGER;
10use serde_json::Value;
11use serde_json::json;
12use uuid::Uuid;
13
14use reactive_graph_std_random_model::RangeI64Properties::HIGH;
15use reactive_graph_std_random_model::RangeI64Properties::LOW;
16use reactive_graph_std_result_model::ResultNumberI64Properties::RESULT;
17
18entity_behaviour!(
19    RandomI64Range,
20    RandomI64RangeFactory,
21    RandomI64RangeFsm,
22    RandomI64RangeBehaviourTransitions,
23    RandomI64RangeValidator
24);
25
26behaviour_validator!(RandomI64RangeValidator, Uuid, ReactiveEntity, TRIGGER.as_ref(), LOW.as_ref(), HIGH.as_ref(), RESULT.as_ref());
27
28impl BehaviourInit<Uuid, ReactiveEntity> for RandomI64RangeBehaviourTransitions {
29    fn init(&self) -> Result<(), BehaviourInitializationFailed> {
30        if self.reactive_instance.as_bool(TRIGGER).unwrap_or(false) {
31            if let Some(low) = self.reactive_instance.as_i64(LOW) {
32                if let Some(high) = self.reactive_instance.as_i64(HIGH) {
33                    if low < high {
34                        self.reactive_instance.set(RESULT, random(low..high));
35                    }
36                }
37            }
38        }
39        Ok(())
40    }
41}
42
43impl BehaviourConnect<Uuid, ReactiveEntity> for RandomI64RangeBehaviourTransitions {
44    fn connect(&self) -> Result<(), BehaviourConnectFailed> {
45        let reactive_instance = self.reactive_instance.clone();
46        self.property_observers.observe_with_handle(TRIGGER.as_ref(), move |trigger: &Value| {
47            if !trigger.as_bool().unwrap_or(false) {
48                return;
49            }
50            let Some(low) = reactive_instance.as_i64(LOW) else {
51                return;
52            };
53            let Some(high) = reactive_instance.as_i64(HIGH) else {
54                return;
55            };
56            if low >= high {
57                return;
58            }
59            reactive_instance.set(RESULT, random(low..high));
60        });
61        Ok(())
62    }
63}
64
65impl BehaviourShutdown<Uuid, ReactiveEntity> for RandomI64RangeBehaviourTransitions {}
66impl BehaviourTransitions<Uuid, ReactiveEntity> for RandomI64RangeBehaviourTransitions {}
67
68fn random(range: Range<i64>) -> Value {
69    let mut rng = rand::rng();
70    json!(rng.random_range(range))
71}