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}