crate::ix!();
#[derive(Getters,Default,Debug,Clone,Deserialize)]
#[getset(get="pub")]
pub struct AccountsConfig {
#[serde(default)] checking: Option<HashMap<u32, String>>,
#[serde(default)] savings: Option<HashMap<u32, String>>,
#[serde(default)] credit: Option<HashMap<u32, String>>,
}
#[derive(Getters,Debug,Clone,Deserialize)]
#[getset(get="pub")]
pub struct GeneralConfig {
#[serde(default)]
long: bool,
}
impl Default for GeneralConfig {
fn default() -> Self {
Self {
long: true,
}
}
}
#[derive(Getters,Clone,Debug,Deserialize)]
#[getset(get="pub")]
pub struct ProgramConfig {
#[serde(flatten)]
#[serde(default)]
general: GeneralConfig,
accounts: Option<AccountsConfig>,
amazon: Option<AmazonConfig>,
config_dir: PathBuf, }
impl ProgramConfig {
pub fn create_amazon_item_map(&self) -> Option<AmazonItemMap>
{
if self.amazon().is_none() {
return None;
}
let amazon = self.amazon().as_ref().unwrap();
create_amazon_item_map(amazon)
}
pub fn csv_path_for(&self, relative_path: &str) -> PathBuf {
self.config_dir.join(relative_path)
}
}
#[derive(Debug, Deserialize)]
struct ProgramConfigIntermediate {
general: GeneralConfig,
accounts: Option<AccountsConfig>,
amazon: Option<AmazonConfig>,
}
pub fn load_program_config_from_path<P: AsRef<Path> + Debug>(
config_path: P
) -> Result<ProgramConfig, ConfigError> {
let config_path = config_path.as_ref().canonicalize()
.expect(&format!("could not canonicalize {:?}", config_path));
let config_dir = config_path
.parent()
.unwrap_or_else(|| Path::new(".")) .to_path_buf();
let builder = ConfigConfig::builder()
.add_source(ConfigFile::from(config_path.as_ref()))
.add_source(ConfigEnvironment::with_prefix("TKTAX"));
let tmp = builder.build()?.try_deserialize::<ProgramConfigIntermediate>()?;
Ok(ProgramConfig {
general: tmp.general,
accounts: tmp.accounts,
amazon: tmp.amazon,
config_dir,
})
}
impl Default for ProgramConfig {
fn default() -> Self {
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
.unwrap_or_else(|_| ".".into());
let config_path = PathBuf::from(&crate_root).join("config.toml");
match load_program_config_from_path(&config_path) {
Ok(cfg) => cfg,
Err(e) => {
panic!("Failed to load ProgramConfig from {:?}: {:#}", config_path, e)
}
}
}
}