1use zng_var::MergeVarBuilder;
2
3use super::*;
4
5#[derive(Default)]
14pub struct SwitchConfig {
15 cfgs: Vec<SwitchCfg>,
16}
17impl SwitchConfig {
18 pub fn new() -> Self {
20 Self::default()
21 }
22
23 pub fn push(&mut self, match_key: impl Fn(&ConfigKey) -> Option<ConfigKey> + Send + Sync + 'static, config: impl AnyConfig) {
28 self.cfgs.push(SwitchCfg {
29 match_key: Box::new(match_key),
30 cfg: Box::new(config),
31 })
32 }
33
34 pub fn push_prefix(&mut self, prefix: impl Into<Txt>, config: impl AnyConfig) {
40 let prefix = prefix.into();
41 if prefix.is_empty() {
42 self.push(|key| Some(key.clone()), config)
43 } else {
44 self.push(move |key| key.strip_prefix(prefix.as_str()).map(Txt::from_str), config)
45 }
46 }
47
48 pub fn with(mut self, match_key: impl Fn(&ConfigKey) -> Option<ConfigKey> + Send + Sync + 'static, config: impl AnyConfig) -> Self {
54 self.push(match_key, config);
55 self
56 }
57
58 pub fn with_prefix(mut self, prefix: impl Into<Txt>, config: impl AnyConfig) -> Self {
64 self.push_prefix(prefix, config);
65 self
66 }
67
68 fn cfg_mut(&mut self, key: &ConfigKey) -> Option<(ConfigKey, &mut dyn AnyConfig)> {
69 for c in &mut self.cfgs {
70 if let Some(key) = (c.match_key)(key) {
71 return Some((key, &mut *c.cfg));
72 }
73 }
74 None
75 }
76}
77impl AnyConfig for SwitchConfig {
78 fn status(&self) -> Var<ConfigStatus> {
79 let mut s = MergeVarBuilder::with_capacity(self.cfgs.len());
80 for c in &self.cfgs {
81 s.push(c.cfg.status());
82 }
83 s.build(|status| ConfigStatus::merge_status(status.iter().cloned()))
84 }
85
86 fn get_raw(&mut self, key: ConfigKey, default: RawConfigValue, insert: bool) -> Var<RawConfigValue> {
87 match self.cfg_mut(&key) {
88 Some((key, cfg)) => cfg.get_raw(key, default, insert),
89 None => const_var(default),
90 }
91 }
92
93 fn contains_key(&mut self, key: ConfigKey) -> Var<bool> {
94 match self.cfg_mut(&key) {
95 Some((key, cfg)) => cfg.contains_key(key),
96 None => const_var(false),
97 }
98 }
99
100 fn remove(&mut self, key: &ConfigKey) -> bool {
101 match self.cfg_mut(key) {
102 Some((key, cfg)) => cfg.remove(&key),
103 None => false,
104 }
105 }
106
107 fn low_memory(&mut self) {
108 for c in &mut self.cfgs {
109 c.cfg.low_memory();
110 }
111 }
112}
113
114struct SwitchCfg {
115 match_key: Box<dyn Fn(&ConfigKey) -> Option<ConfigKey> + Send + Sync>,
116 cfg: Box<dyn AnyConfig>,
117}