reactive_graph_sys_config/behaviour/component/
config_file.rs1use std::path::Path;
2
3use log::error;
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 uuid::Uuid;
12
13use reactive_graph_std_result_model::ResultObjectProperties::RESULT;
14use reactive_graph_sys_file_model::FileProperties::FILENAME;
15
16entity_behaviour!(ConfigFile, ConfigFileFactory, ConfigFileFsm, ConfigFileBehaviourTransitions, ConfigFileValidator);
17
18behaviour_validator!(ConfigFileValidator, Uuid, ReactiveEntity, TRIGGER.as_ref(), RESULT.as_ref(), FILENAME.as_ref());
19
20impl BehaviourInit<Uuid, ReactiveEntity> for ConfigFileBehaviourTransitions {
21 fn init(&self) -> Result<(), BehaviourInitializationFailed> {
22 if let Some(data) = self.reactive_instance.as_string(FILENAME).and_then(read_toml) {
23 self.reactive_instance.set(RESULT, data);
24 }
25 Ok(())
26 }
27}
28
29impl BehaviourConnect<Uuid, ReactiveEntity> for ConfigFileBehaviourTransitions {
30 fn connect(&self) -> Result<(), BehaviourConnectFailed> {
31 let reactive_instance = self.reactive_instance.clone();
32 self.property_observers.observe_with_handle(TRIGGER.as_ref(), move |trigger: &Value| {
33 if !trigger.as_bool().unwrap_or(false) {
34 return;
35 }
36 if let Some(data) = reactive_instance.as_string(FILENAME).and_then(read_toml) {
37 reactive_instance.set(RESULT, data);
38 }
39 });
40 Ok(())
41 }
42}
43
44impl BehaviourShutdown<Uuid, ReactiveEntity> for ConfigFileBehaviourTransitions {}
45impl BehaviourTransitions<Uuid, ReactiveEntity> for ConfigFileBehaviourTransitions {}
46
47fn read_toml(filename: String) -> Option<Value> {
48 let filename = shellexpand::tilde(&filename);
49 let path = Path::new(filename.as_ref());
50 let toml_config = std::fs::read_to_string(path);
51 match toml_config {
52 Ok(toml_config) => {
53 let data = toml::from_str::<Value>(toml_config.as_str());
54 match data {
55 Ok(data) => Some(data),
56 Err(e) => {
57 error!("Failed to parse config file {}: {}", filename, e);
58 None
59 }
60 }
61 }
62 Err(e) => {
63 error!("config file {} does not exist: {}", filename, e);
64 None
65 }
66 }
67}