Skip to main content

mod_installer/config/
log_options.rs

1use std::{error::Error, path::PathBuf};
2
3use crate::config::args::path_must_exist;
4
5pub const PATH_PROVIDED_ERROR: &str = "Path provided, does not exist: ";
6
7pub const WEIDU_LOG_MODE_ERROR: &str = r"
8Please provide a valid weidu logging setting, options are:
9--weidu-log-mode log X       log output and details to X
10--weidu-log-mode autolog     log output and details to WSETUP.DEBUG
11--weidu-log-mode logapp      append to log instead of overwriting
12--weidu-log-mode log-extern  also log output from commands invoked by WeiDU
13";
14
15#[derive(Debug, PartialEq, Clone)]
16pub enum LogOptions {
17  Log(PathBuf),
18  AutoLog,
19  LogAppend,
20  LogExternal,
21}
22
23impl TryFrom<&str> for LogOptions {
24  type Error = Box<dyn Error>;
25
26  fn try_from(value: &str) -> Result<Self, Self::Error> {
27    match value {
28      x if x.starts_with("log ") => {
29        if let Some((_, tail)) = value.split_once(' ') {
30          if let Ok(path) = path_must_exist(tail) {
31            #[cfg(not(target_os = "windows"))]
32            return Ok(LogOptions::Log(path.canonicalize()?));
33            #[cfg(windows)]
34            return Ok(LogOptions::Log(path));
35          }
36          return Err(format!("{} {:?}", PATH_PROVIDED_ERROR, tail).into());
37        }
38        Err(format!("{WEIDU_LOG_MODE_ERROR}, Provided {value}").into())
39      },
40      "autolog" => Ok(LogOptions::AutoLog),
41      "logapp" => Ok(LogOptions::LogAppend),
42      "log-extern" => Ok(LogOptions::LogExternal),
43      _ => Err(format!("{WEIDU_LOG_MODE_ERROR}, Provided {value}").into()),
44    }
45  }
46}
47
48impl LogOptions {
49  pub fn value_parser(arg: &str) -> Result<LogOptions, String> {
50    LogOptions::try_from(arg).map_err(|err| err.to_string())
51  }
52  pub fn to_args(&self, path: &str) -> Vec<String> {
53    match self {
54      LogOptions::LogAppend => vec!["--logapp".to_string()],
55      LogOptions::Log(path_buf) if path_buf.is_file() => vec![
56        "--log".to_string(),
57        path_buf
58          .as_os_str()
59          .to_str()
60          .unwrap_or_default()
61          .to_string(),
62      ],
63      LogOptions::Log(path_buf) => vec![
64        "--log".to_string(),
65        path_buf
66          .join(path)
67          .as_os_str()
68          .to_str()
69          .unwrap_or_default()
70          .to_string(),
71      ],
72      LogOptions::AutoLog => vec!["--autolog".to_string()],
73      LogOptions::LogExternal => vec!["--log-extern".to_string()],
74    }
75  }
76}
77
78#[cfg(test)]
79mod tests {
80
81  use super::*;
82  use pretty_assertions::assert_eq;
83
84  #[test]
85  fn test_parse_weidu_log_mode() -> Result<(), Box<dyn Error>> {
86    let tests = vec![
87      (
88        "log log",
89        Err("No such file or directory (os error 2)".to_string()),
90      ),
91      ("autolog", Ok(LogOptions::AutoLog)),
92      ("logapp", Ok(LogOptions::LogAppend)),
93      ("log-extern", Ok(LogOptions::LogExternal)),
94      ("", Err(format!("{WEIDU_LOG_MODE_ERROR}, Provided "))),
95    ];
96    for (test, expected) in tests {
97      let result = LogOptions::value_parser(test);
98      assert_eq!(
99        result, expected,
100        "Result {result:?} didn't match Expected {expected:?}",
101      );
102    }
103    Ok(())
104  }
105}