1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use crate::module::{AppModBuilder, AppModInitOptions};

pub struct AppModConfigGetter<'a> {
    pub ns: &'a Option<String>,
    pub bld: &'a AppModBuilder,
    pub name: String,
}

impl<'a> AppModConfigGetter<'a> {
    pub fn new<T>(o: &'a AppModInitOptions<T>, bld: &'a AppModBuilder, name: &str) -> Self {
        AppModConfigGetter {
            ns: &o.ns,
            bld,
            name: name.to_string(),
        }
    }

    pub fn get_or<T>(&self, key: &str, default: &T) -> T
    where
        T: Clone + std::str::FromStr,
    {
        let key = self.create_key(key);
        let s = match self.bld.app.config.get(&key) {
            Some(s) => s,
            None => return default.clone(),
        };

        match s.parse::<T>() {
            Ok(v) => v,
            Err(_) => {
                eprintln!("Failed to parse config value for key '{}'.", key);
                default.clone()
            }
        }
    }

    pub fn get_or_panic<T>(&self, key: &str) -> T
    where
        T: Clone + std::str::FromStr,
    {
        let key = self.create_key(key);
        let s = match self.bld.app.config.get(&key) {
            Some(s) => s,
            None => panic!("Config value for key '{}' not found.", key),
        };

        match s.parse::<T>() {
            Ok(v) => v,
            Err(_) => {
                panic!("Failed to parse config value for key '{}'.", key);
            }
        }
    }

    fn create_key(&self, key: &str) -> String {
        match self.ns {
            Some(ns) => format!("{}_{}_{}", ns, self.name, key),
            None => format!("{}_{}", self.name, key),
        }
        .to_uppercase()
    }
}