config_parser2/
lib.rs

1pub use anyhow::Result;
2
3pub trait ConfigParser {
4    fn parse(&mut self, value: toml::Value) -> Result<()>;
5}
6
7pub use config_parser_derive::ConfigParse;
8
9#[macro_export]
10macro_rules! config_parser_impl {
11    ($($t:ty),+) => {
12        $(
13            impl ConfigParser for $t {
14                fn parse(&mut self, value: toml::Value) -> Result<()> {
15                    *self = value.try_into::<$t>()?;
16                    Ok(())
17                }
18            }
19        )*
20    };
21}
22
23impl<'de, T> ConfigParser for Option<T>
24where
25    T: serde::de::Deserialize<'de>,
26{
27    fn parse(&mut self, value: toml::Value) -> Result<()> {
28        if let Ok(value) = value.try_into::<T>() {
29            *self = Some(value);
30        }
31        Ok(())
32    }
33}
34
35impl<'de, T> ConfigParser for Vec<T>
36where
37    T: serde::de::Deserialize<'de>,
38{
39    fn parse(&mut self, value: toml::Value) -> Result<()> {
40        if let toml::Value::Array(array) = value {
41            let result: Result<Vec<_>> =
42                array.into_iter().map(|e| Ok(e.try_into::<T>()?)).collect();
43            match result {
44                Err(err) => Err(err),
45                Ok(value) => {
46                    *self = value;
47                    Ok(())
48                }
49            }
50        } else {
51            Err(anyhow::anyhow!(
52                "config parsing error: expect a TOML::Array, receive {:?}",
53                value
54            ))
55        }
56    }
57}
58
59config_parser_impl!(
60    String, usize, u128, u64, u32, u16, u8, isize, i128, i64, i32, i16, i8, f64, f32, bool, char
61);