mei/
config.rs

1use {
2    crate::tool::Tools,
3    std::{env, fs},
4    toml::{Document, Value},
5};
6
7pub(crate) struct Config {
8    pub verbose: Verbose,
9    pub tools: Tools,
10}
11
12impl Config {
13    pub fn load() -> Self {
14        let doc: Document = {
15            let path = "Cargo.toml";
16            let content = match fs::read_to_string(path) {
17                Ok(content) => content,
18                Err(err) => panic!("failed to read {path}: {err}"),
19            };
20
21            match content.parse() {
22                Ok(doc) => doc,
23                Err(err) => panic!("failed to parse {path}: {err}"),
24            }
25        };
26
27        let mei = doc
28            .get("package")
29            .or_else(|| doc.get("workspace"))
30            .and_then(|p| p.get("metadata")?.get("mei"));
31
32        let verbose = Verbose::from_var()
33            .or_else(|| Verbose::from_toml(mei?.get("verbose")?.as_value()?))
34            .unwrap_or_default();
35
36        let tools = mei
37            .and_then(|m| Some(Tools::from_toml(m.get("tools")?.as_table_like()?)))
38            .unwrap_or_default();
39
40        Self { verbose, tools }
41    }
42}
43
44#[derive(Clone, Copy, Default)]
45pub(crate) enum Verbose {
46    #[default]
47    No,
48    Yes,
49    Full,
50}
51
52impl Verbose {
53    fn from_var() -> Option<Self> {
54        let val = env::var("MAI_VERBOSE").ok()?;
55        match &val[..] {
56            "0" => Some(Self::No),
57            "1" => Some(Self::Yes),
58            "full" => Some(Self::Full),
59            _ => None,
60        }
61    }
62
63    fn from_toml(val: &Value) -> Option<Self> {
64        match val {
65            Value::String(s) if s.value() == "full" => Some(Self::Full),
66            Value::Boolean(f) if *f.value() => Some(Self::Yes),
67            Value::Boolean(_) => Some(Self::No),
68            _ => None,
69        }
70    }
71
72    pub fn enabled(self) -> bool {
73        matches!(self, Self::Yes | Self::Full)
74    }
75}