Skip to main content

datex_core/runtime/
config.rs

1use crate::{
2    collections::HashMap,
3    network::com_hub::InterfacePriority,
4    prelude::*,
5    serde::{
6        Deserialize, error::SerializationError, serializer::to_value_container,
7    },
8    values::{
9        core_values::endpoint::Endpoint, value_container::ValueContainer,
10    },
11};
12use serde::Serialize;
13
14pub fn is_priority_none(v: &InterfacePriority) -> bool {
15    matches!(v, InterfacePriority::None)
16}
17
18#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
19#[cfg_attr(feature = "wasm_runtime", derive(tsify::Tsify))]
20pub struct RuntimeConfigInterface {
21    #[serde(rename = "type")]
22    pub interface_type: String,
23    #[serde(rename = "config")]
24    #[cfg_attr(feature = "wasm_runtime", tsify(type = "unknown"))]
25    pub setup_data: ValueContainer,
26
27    #[serde(default, skip_serializing_if = "is_priority_none")]
28    pub priority: InterfacePriority,
29}
30
31impl RuntimeConfigInterface {
32    pub fn new<T: Serialize>(
33        interface_type: &str,
34        setup_data: T,
35    ) -> Result<RuntimeConfigInterface, SerializationError> {
36        Ok(RuntimeConfigInterface {
37            interface_type: interface_type.to_string(),
38            priority: InterfacePriority::default(),
39            setup_data: to_value_container(&setup_data)?,
40        })
41    }
42
43    pub fn new_from_value_container(
44        interface_type: &str,
45        config: ValueContainer,
46    ) -> RuntimeConfigInterface {
47        RuntimeConfigInterface {
48            priority: InterfacePriority::default(),
49            interface_type: interface_type.to_string(),
50            setup_data: config,
51        }
52    }
53}
54
55#[derive(Debug, Default, Deserialize, Serialize)]
56pub struct RuntimeConfig {
57    pub endpoint: Option<Endpoint>,
58    pub interfaces: Option<Vec<RuntimeConfigInterface>>,
59    pub env: Option<HashMap<String, String>>,
60}
61
62impl RuntimeConfig {
63    pub fn new_with_endpoint(endpoint: Endpoint) -> Self {
64        RuntimeConfig {
65            endpoint: Some(endpoint),
66            interfaces: None,
67            env: None,
68        }
69    }
70
71    pub fn add_interface<T: Serialize>(
72        &mut self,
73        interface_type: String,
74        config: T,
75        priority: InterfacePriority,
76    ) -> Result<(), SerializationError> {
77        let config = to_value_container(&config)?;
78        let interface = RuntimeConfigInterface {
79            interface_type,
80            setup_data: config,
81            priority,
82        };
83        if let Some(interfaces) = &mut self.interfaces {
84            interfaces.push(interface);
85        } else {
86            self.interfaces = Some(vec![interface]);
87        }
88
89        Ok(())
90    }
91
92    /// Adds a single environment variable to the runtime's custom environment variables.
93    pub fn add_env_var(&mut self, key: String, value: String) {
94        self.env.get_or_insert_with(HashMap::new).insert(key, value);
95    }
96
97    /// Adds multiple environment variables to the runtime's custom environment variables.
98    pub fn add_env_vars(&mut self, vars: HashMap<String, String>) {
99        self.env.get_or_insert_with(HashMap::new).extend(vars);
100    }
101
102    #[cfg(feature = "target_native")]
103    /// Adds all host environment variables to the runtime's custom environment variables.
104    pub fn load_host_env_vars(&mut self) {
105        // add all host environment variables to the runtime's custom environment variables
106        for (key, value) in std::env::vars() {
107            self.env.get_or_insert_with(HashMap::new).insert(key, value);
108        }
109    }
110
111    #[cfg(feature = "target_native")]
112    /// Adds all environment variables from a .env file to the runtime's custom environment variables.
113    pub fn add_env_vars_from_file(
114        &mut self,
115        path: &std::path::PathBuf,
116    ) -> Result<(), dotenvy::Error> {
117        let loader1 = dotenvy::from_path_iter(path)?;
118        for item in loader1 {
119            let (key, val) = item?;
120            self.env.get_or_insert_with(HashMap::new).insert(key, val);
121        }
122        Ok(())
123    }
124}
125
126#[cfg(test)]
127pub mod tests {
128    use crate::{prelude::*, runtime::RuntimeConfig};
129
130    #[test]
131    fn test_add_env_var() {
132        let mut config = RuntimeConfig::default();
133        config.add_env_var("KEY1".to_string(), "VALUE1".to_string());
134        let env_vars = config.env.unwrap();
135        assert_eq!(env_vars.get("KEY1"), Some(&"VALUE1".to_string()));
136    }
137}