clap_config_file_core/
lib.rs1use clap::Parser;
2use serde::{Deserialize, Serialize};
3
4#[derive(Parser, Debug, Default, Deserialize, Serialize)]
5#[command(trailing_var_arg = true)]
6pub struct ConfigFile {
7 #[arg(long = "no-config", default_value_t = false)]
9 pub no_config: bool,
10
11 #[arg(long = "config-file")]
13 pub config_file: Option<std::path::PathBuf>,
14
15 #[arg(long = "config")]
17 pub raw_config: Option<String>,
18
19 #[arg(last = true)]
21 pub leftover: Vec<String>,
22}
23
24impl ConfigFile {
25 pub fn load(default_config: &str) -> Self {
26 let args = if cfg!(test) {
27 if let Ok(args) = std::env::var("ARGS_TEST") {
28 Self::parse_from(args.split_whitespace())
29 } else {
30 Self::parse()
31 }
32 } else {
33 Self::parse()
34 };
35
36 if args.no_config {
37 return args;
38 }
39
40 if let Some(raw_config) = args.raw_config.as_ref() {
42 if let Ok(config) = serde_yaml::from_str(raw_config) {
43 return config;
44 }
45 }
46
47 if let Some(config_path) = args.config_file.as_ref() {
49 match std::fs::read_to_string(config_path) {
50 Ok(contents) => {
51 if let Ok(config) = serde_yaml::from_str(&contents) {
52 return config;
53 }
54 }
55 Err(e) => eprintln!("Failed to read config file: {}", e),
56 }
57 }
58
59 if let Ok(config) = serde_yaml::from_str(default_config) {
61 return config;
62 }
63
64 args
65 }
66}