Skip to main content

minion_engine/config/
mod.rs

1pub mod manager;
2pub mod merge;
3
4pub use manager::ConfigManager;
5
6use std::collections::HashMap;
7use std::time::Duration;
8
9/// Resolved configuration for a specific step (after 4-layer merge)
10#[derive(Debug, Clone, Default)]
11pub struct StepConfig {
12    pub values: HashMap<String, serde_json::Value>,
13}
14
15#[allow(dead_code)]
16impl StepConfig {
17    pub fn get_str(&self, key: &str) -> Option<&str> {
18        self.values.get(key).and_then(|v| v.as_str())
19    }
20
21    pub fn get_bool(&self, key: &str) -> bool {
22        self.values
23            .get(key)
24            .and_then(|v| v.as_bool())
25            .unwrap_or(false)
26    }
27
28    pub fn get_duration(&self, key: &str) -> Option<Duration> {
29        let s = self.get_str(key)?;
30        parse_duration(s)
31    }
32
33    pub fn get_u64(&self, key: &str) -> Option<u64> {
34        self.values.get(key).and_then(|v| v.as_u64())
35    }
36}
37
38pub fn parse_duration(s: &str) -> Option<Duration> {
39    let s = s.trim();
40    // Check "ms" before "s" to avoid "100ms" matching as seconds
41    if let Some(ms) = s.strip_suffix("ms") {
42        ms.trim().parse::<u64>().ok().map(Duration::from_millis)
43    } else if let Some(secs) = s.strip_suffix('s') {
44        secs.trim().parse::<u64>().ok().map(Duration::from_secs)
45    } else if let Some(mins) = s.strip_suffix('m') {
46        mins.trim()
47            .parse::<u64>()
48            .ok()
49            .map(|m| Duration::from_secs(m * 60))
50    } else {
51        s.parse::<u64>().ok().map(Duration::from_secs)
52    }
53}