libgir/config/
error.rs

1use log::error;
2
3pub trait TomlHelper
4where
5    Self: Sized,
6{
7    fn check_unwanted(&self, options: &[&str], err_msg: &str);
8    fn lookup<'a>(&'a self, option: &str) -> Option<&'a toml::Value>;
9    fn lookup_str<'a>(&'a self, option: &'a str, err: &str) -> Result<&'a str, String>;
10    fn lookup_vec<'a>(&'a self, option: &'a str, err: &str) -> Result<&'a Vec<Self>, String>;
11    fn as_result_str<'a>(&'a self, option: &'a str) -> Result<&'a str, String>;
12    fn as_result_vec<'a>(&'a self, option: &'a str) -> Result<&'a Vec<Self>, String>;
13    fn as_result_bool<'a>(&'a self, option: &'a str) -> Result<bool, String>;
14}
15
16impl TomlHelper for toml::Value {
17    fn check_unwanted(&self, options: &[&str], err_msg: &str) {
18        let mut ret = Vec::new();
19        let Some(table) = self.as_table() else { return };
20        for (key, _) in table.iter() {
21            if !options.contains(&key.as_str()) {
22                ret.push(key.clone());
23            }
24        }
25        if !ret.is_empty() {
26            error!(
27                "\"{}\": Unknown key{}: {:?}",
28                err_msg,
29                if ret.len() > 1 { "s" } else { "" },
30                ret
31            );
32        }
33    }
34    fn lookup<'a>(&'a self, option: &str) -> Option<&'a toml::Value> {
35        let mut value = self;
36        for opt in option.split('.') {
37            let table = value.as_table()?;
38            value = table.get(opt)?;
39        }
40        Some(value)
41    }
42    fn lookup_str<'a>(&'a self, option: &'a str, err: &str) -> Result<&'a str, String> {
43        let value = self.lookup(option).ok_or(err)?;
44        value.as_result_str(option)
45    }
46    fn lookup_vec<'a>(&'a self, option: &'a str, err: &str) -> Result<&'a Vec<Self>, String> {
47        let value = self.lookup(option).ok_or(err)?;
48        value.as_result_vec(option)
49    }
50    fn as_result_str<'a>(&'a self, option: &'a str) -> Result<&'a str, String> {
51        self.as_str().ok_or_else(|| {
52            format!(
53                "Invalid `{}` value, expected a string, found {}",
54                option,
55                self.type_str()
56            )
57        })
58    }
59    fn as_result_vec<'a>(&'a self, option: &'a str) -> Result<&'a Vec<Self>, String> {
60        self.as_array().ok_or_else(|| {
61            format!(
62                "Invalid `{}` value, expected a array, found {}",
63                option,
64                self.type_str()
65            )
66        })
67    }
68    fn as_result_bool<'a>(&'a self, option: &'a str) -> Result<bool, String> {
69        self.as_bool().ok_or_else(|| {
70            format!(
71                "Invalid `{}` value, expected a boolean, found {}",
72                option,
73                self.type_str()
74            )
75        })
76    }
77}