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}