tktax_config/
program_config.rs1crate::ix!();
3
4#[derive(Getters,Default,Debug,Clone,Deserialize)]
5#[getset(get="pub")]
6pub struct AccountsConfig {
7 #[serde(default)] checking: Option<HashMap<u32, String>>,
8 #[serde(default)] savings: Option<HashMap<u32, String>>,
9 #[serde(default)] credit: Option<HashMap<u32, String>>,
10}
11
12#[derive(Getters,Debug,Clone,Deserialize)]
13#[getset(get="pub")]
14pub struct GeneralConfig {
15
16 #[serde(default)]
17 long: bool,
18}
19
20impl Default for GeneralConfig {
21
22 fn default() -> Self {
23 Self {
24 long: true,
25 }
26 }
27}
28
29#[derive(Getters,Clone,Debug,Deserialize)]
31#[getset(get="pub")]
32pub struct ProgramConfig {
33
34 #[serde(flatten)]
35 #[serde(default)]
36 general: GeneralConfig,
37
38 accounts: Option<AccountsConfig>,
39 amazon: Option<AmazonConfig>,
40
41 config_dir: PathBuf, }
44
45impl ProgramConfig {
46
47 pub fn create_amazon_item_map(&self) -> Option<AmazonItemMap>
48 {
49 if self.amazon().is_none() {
50 return None;
51 }
52
53 let amazon = self.amazon().as_ref().unwrap();
54
55 create_amazon_item_map(amazon)
56 }
57
58 pub fn csv_path_for(&self, relative_path: &str) -> PathBuf {
60 self.config_dir.join(relative_path)
61 }
62}
63
64#[derive(Debug, Deserialize)]
66struct ProgramConfigIntermediate {
67 general: GeneralConfig,
68 accounts: Option<AccountsConfig>,
69 amazon: Option<AmazonConfig>,
70}
71
72pub fn load_program_config_from_path<P: AsRef<Path> + Debug>(
73 config_path: P
74) -> Result<ProgramConfig, ConfigError> {
75
76 let config_path = config_path.as_ref().canonicalize()
77 .expect(&format!("could not canonicalize {:?}", config_path));
78
79 let config_dir = config_path
80 .parent()
81 .unwrap_or_else(|| Path::new(".")) .to_path_buf();
83
84 let builder = ConfigConfig::builder()
86 .add_source(ConfigFile::from(config_path.as_ref()))
87 .add_source(ConfigEnvironment::with_prefix("TKTAX"));
88
89 let tmp = builder.build()?.try_deserialize::<ProgramConfigIntermediate>()?;
91
92 Ok(ProgramConfig {
94 general: tmp.general,
95 accounts: tmp.accounts,
96 amazon: tmp.amazon,
97 config_dir,
98 })
99}
100
101impl Default for ProgramConfig {
102 fn default() -> Self {
103 let crate_root = std::env::var("CARGO_MANIFEST_DIR")
104 .unwrap_or_else(|_| ".".into()); let config_path = PathBuf::from(&crate_root).join("config.toml");
108
109 match load_program_config_from_path(&config_path) {
114 Ok(cfg) => cfg,
115 Err(e) => {
116 panic!("Failed to load ProgramConfig from {:?}: {:#}", config_path, e)
119 }
120 }
121 }
122}