diff --git a/src/config.rs b/src/config.rs index b101277..e482a9f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use std::fmt::Display; use std::path::PathBuf; +use std::str::FromStr; pub const HELP_MESSAGE: &str = r#"call [options] [--] [arguments] Options: @@ -10,6 +11,10 @@ Options: --bin=xxx Specify executable file --config=xxx Specify configuration file --help Print this help message +Defaults: + hide console + chdir ./lib + run ./main "#; #[derive(Clone)] @@ -17,7 +22,7 @@ pub struct Config { pub show_console: bool, pub chdir: Option, pub bin: PathBuf, - pub config: Option, + pub config: Option, pub bin_arg: Vec, } @@ -36,12 +41,92 @@ impl Display for Config { } impl Config { - pub fn from_cli() -> Option { + pub fn new( + show_console: bool, + chdir: Option, + bin: PathBuf, + config: Option, + bin_arg: Vec, + ) -> Self { + Config { + show_console, + chdir, + bin, + config, + bin_arg, + } + } + pub fn merge_from(&mut self, other: &Config) { + if other.show_console { + self.show_console = true; + } + if other.chdir.is_some() { + self.chdir = other.chdir.clone(); + } + if other.bin != PathBuf::from("./lib/main") { + self.bin = other.bin.clone(); + } + if other.config.is_some() { + self.config = other.config.clone(); + } + if !other.bin_arg.is_empty() { + self.bin_arg = other.bin_arg.clone(); + } + } + pub fn from_config(config_path: Option) -> Option { + if config_path.is_none() { + // 判断一下 ./run.conf 是否存在 + let config_path = PathBuf::from("./run.conf"); + if config_path.exists() { + return Self::from_config(Some(config_path)); + } + return None; + } + let config_path = config_path.unwrap(); + if !config_path.exists() { + return None; + } + let config_str = std::fs::read_to_string(config_path).unwrap(); let mut show_console = false; let mut chdir: Option = None; let mut bin: Option = None; - let dir: Option = None; - let mut config: Option = None; + let mut arg: Option = None; + for line in config_str.lines() { + if line.starts_with("#") { + continue; + } + let mut iter = line.splitn(2, "="); + let key = iter.next().unwrap(); + let value = iter.next().unwrap(); + if key == "show_console" { + show_console = value == "true"; + } else if key == "chdir" { + chdir = Some(value.to_string()); + } else if key == "bin" { + bin = Some(value.to_string()); + } else if key == "arg" { + arg = Some(value.to_string()); + } + } + // 处理一下 bin + let bin = if let Some(bin) = bin { + PathBuf::from(bin) + } else { + PathBuf::from("./lib/main") + }; + let chdir = chdir.map(|x| PathBuf::from(x)); + let arg = if let Some(arg) = arg { + vec![arg] + } else { + Vec::new() + }; + Some(Self::new(show_console, chdir, bin, None, arg)) + } + pub fn from_cli() -> Option { + let mut show_console = false; + let mut chdir: Option = None; + let mut bin: Option = None; + let mut config: Option = None; // -- 表示后面的参数都是可执行文件的参数 let args: Vec = std::env::args().collect(); // 先检查有没有 --help @@ -78,22 +163,27 @@ impl Config { } else if args[i].starts_with("--bin=") { bin = Some(args[i][6..].to_string()); } else if args[i].starts_with("--config=") { - config = Some(args[i][9..].to_string()); + config = Some(PathBuf::from_str(&args[i][9..]).unwrap()); } } - // 拼接上 dir - let bin = if let Some(dir) = dir { - PathBuf::from(dir).join(bin.unwrap_or("main".to_string())) + // 处理一下 bin + let bin = if let Some(bin) = bin { + PathBuf::from(bin) } else { - PathBuf::from(bin.unwrap_or("./lib/main".to_string())) + PathBuf::from("./main") }; - let chdir = chdir.map(|x| PathBuf::from(x)); - Some(Config { - show_console, - chdir, - bin, - config, - bin_arg, - }) + // 默认为 chdir ./lib + let chdir = if let Some(chdir) = chdir { + Some(PathBuf::from(chdir)) + } else { + Some(PathBuf::from("./lib")) + }; + + let mut conf = Self::new(show_console, chdir, bin, config, bin_arg); + let conf_from_config = Self::from_config(conf.config.clone()); + if conf_from_config.is_some() { + conf.merge_from(&conf_from_config.unwrap()); + } + Some(conf) } }