Added Cli flag for indicating the input file date field uses ISO 8601 formatting. Also separated flattened Cli struct more. Resolves #48.

This commit is contained in:
scoobybejesus 2019-10-06 15:05:45 -04:00
parent 8567dd04b0
commit 7002923a4c
5 changed files with 64 additions and 35 deletions

View File

@ -53,6 +53,7 @@ pub struct ImportProcessParameters {
pub costing_method: InventoryCostingMethod,
pub lk_cutoff_date_string: String,
pub date_separator: String,
pub iso_date_style: bool,
}
pub(crate) fn import_and_process_final(
@ -79,6 +80,7 @@ pub(crate) fn import_and_process_final(
&mut raw_account_map,
&mut account_map,
&settings.date_separator,
settings.iso_date_style,
) {
Ok(()) => { println!("Successfully imported csv file."); }
Err(err) => {
@ -96,6 +98,7 @@ pub(crate) fn import_and_process_final(
raw_acct_map: &mut HashMap<u16, RawAccount>,
acct_map: &mut HashMap<u16, Account>,
date_separator: &str,
iso_date_style: bool,
) -> Result<(), Box<dyn Error>> {
let file = File::open(import_file_path)?; println!("CSV ledger file opened successfully.\n");
@ -111,6 +114,7 @@ pub(crate) fn import_and_process_final(
transactions_map,
action_records,
date_separator,
iso_date_style,
)?;
Ok(())

View File

@ -112,6 +112,7 @@ pub(crate) fn import_transactions(
txns_map: &mut HashMap<u32, Transaction>,
action_records: &mut HashMap<u32, ActionRecord>,
sep: &str,
iso: bool,
) -> Result<(), Box<dyn Error>> {
let mut this_tx_number = 0;
@ -200,11 +201,19 @@ pub(crate) fn import_transactions(
None => {}
}
let format_yy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%y");
let format_yyyy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%Y");
let format_yy: String;
let format_yyyy: String;
let tx_date = NaiveDate::parse_from_str(this_tx_date, format_yy)
.unwrap_or(NaiveDate::parse_from_str(this_tx_date, format_yyyy)
if iso {
format_yyyy = "%Y".to_owned() + sep + &"%d" + sep + "%m";
format_yy = "%y".to_owned() + sep + &"%d" + sep + "%m";
} else {
format_yyyy = "%m".to_owned() + sep + &"%d" + sep + "%Y";
format_yy = "%m".to_owned() + sep + &"%d" + sep + "%y";
}
let tx_date = NaiveDate::parse_from_str(this_tx_date, &format_yy)
.unwrap_or(NaiveDate::parse_from_str(this_tx_date, &format_yyyy)
.expect("\nFailed to parse date in input file. Check date separator character. Also %m/%d/%y (or %Y) format is required.\n")
);

View File

@ -36,19 +36,48 @@ pub(crate) struct Cli {
#[structopt(flatten)]
flags: Flags,
#[structopt(flatten)]
opts: Options,
/// File to be imported. (Currently, the only supported date format is %m/%d/%y.)
#[structopt(name = "file", parse(from_os_str))]
file_to_import: Option<PathBuf>,
}
/// Output directory for exported reports.
#[structopt(name = "output directory", short, long = "output", default_value = ".", parse(from_os_str))]
output_dir_path: PathBuf,
#[derive(StructOpt, Debug)]
pub(crate) struct Flags {
/// User is instructing the program to skip the data entry wizard.
/// When set, program will error without required command-line args.
#[structopt(name = "accept args", short = "a", long = "accept")]
accept_args: bool,
/// This will cause the program to expect the txDate field in the file_to_import to use the format
/// YYYY-MM-dd or YY-MM-dd (or YYYY/MM/dd or YY/MM/dd, depending on the date-separator option)
/// instead of the default US-style MM-dd-YYYY or MM-dd-YY (or MM/dd/YYYY or MM/dd/YY, depending on the
/// date separator option).
#[structopt(name = "date conforms to ISO 8601", short = "i", long = "iso")]
iso_date: bool,
/// This will prevent the program from writing reports to files.
/// This will be ignored if -a is not set (the wizard will always ask to output).
#[structopt(name = "suppress reports", short, long = "suppress")]
suppress_reports: bool,
}
#[derive(StructOpt, Debug)]
pub(crate) struct Options {
/// Choose "h" or "s" for hyphen or slash (i.e., "-" or "/") to indicate the separator character used
/// in the input file txDate column (i.e. 2017/12/31 or 2017-12-31).
#[structopt(name = "date separator character", short, long = "date-separator", default_value = "h", parse(from_os_str))]
date_separator: OsString,
/// Home currency (currency in which all resulting reports are denominated).
/// (Only available as a command line setting.)
#[structopt(name = "home currency", short = "c", long = "currency", default_value = "USD", parse(from_os_str))]
home_currency: OsString,
/// Cutoff date through which like-kind exchange treatment should be applied.
/// Please use %y-%m-%d (or %Y-%m-%d) format for like-kind cutoff date entry.
#[structopt(name = "like-kind cutoff date", short, long = "lk-cutoff", parse(from_os_str))]
@ -64,24 +93,9 @@ pub(crate) struct Cli {
")]
inv_costing_method: OsString,
/// Home currency (currency in which all resulting reports are denominated).
/// (Only available as a command line setting.)
#[structopt(name = "home currency", short = "c", long = "currency", default_value = "USD", parse(from_os_str))]
home_currency: OsString,
}
#[derive(StructOpt, Debug)]
pub(crate) struct Flags {
/// User is instructing the program to skip the data entry wizard.
/// When set, program will error without required command-line args.
#[structopt(name = "accept args", short, long = "accept")]
accept_args: bool,
/// This will prevent the program from writing reports to files.
/// This will be ignored if -a is not set (the wizard will always ask to output).
#[structopt(name = "suppress reports", short, long = "suppress")]
suppress_reports: bool,
/// Output directory for exported reports.
#[structopt(name = "output directory", short, long = "output", default_value = ".", parse(from_os_str))]
output_dir_path: PathBuf,
}

View File

@ -20,7 +20,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
bool
), Box<dyn Error>> {
let date_separator = match args.date_separator.into_string().unwrap().as_str() {
let date_separator = match args.opts.date_separator.into_string().unwrap().as_str() {
"h" => {"-"}
"s" => {"/"}
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
@ -35,16 +35,16 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
input_file_path = cli_user_choices::choose_file_for_import()?;
}
let output_dir_path = args.output_dir_path;
let output_dir_path = args.opts.output_dir_path;
let costing_method_choice = cli_user_choices::inv_costing_from_cmd_arg(args.inv_costing_method)?;
let costing_method_choice = cli_user_choices::inv_costing_from_cmd_arg(args.opts.inv_costing_method)?;
let home_currency_choice = args.home_currency.into_string().unwrap().to_uppercase();
let home_currency_choice = args.opts.home_currency.into_string().unwrap().to_uppercase();
let like_kind_election;
let like_kind_cutoff_date_string: String;
if let Some(date) = args.lk_cutoff_date {
if let Some(date) = args.opts.lk_cutoff_date {
like_kind_election = true;
like_kind_cutoff_date_string = date.into_string().unwrap();
} else {
@ -59,6 +59,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
enable_like_kind_treatment: like_kind_election,
lk_cutoff_date_string: like_kind_cutoff_date_string,
date_separator: date_separator.to_string(),
iso_date_style: args.flags.iso_date
};
let (

View File

@ -24,7 +24,7 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
shall_we_proceed()?;
let date_separator = match args.date_separator.into_string().unwrap().as_str() {
let date_separator = match args.opts.date_separator.into_string().unwrap().as_str() {
"h" => {"-"}
"s" => {"/"}
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
@ -38,15 +38,15 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
input_file_path = cli_user_choices::choose_file_for_import()?;
}
let output_dir_path = args.output_dir_path;
let output_dir_path = args.opts.output_dir_path;
let costing_method_choice = cli_user_choices::choose_inventory_costing_method(args.inv_costing_method)?;
let costing_method_choice = cli_user_choices::choose_inventory_costing_method(args.opts.inv_costing_method)?;
let home_currency_choice = args.home_currency.into_string().unwrap().to_uppercase();
let home_currency_choice = args.opts.home_currency.into_string().unwrap().to_uppercase();
let lk_cutoff_date_opt_string;
if let Some(lk_cutoff) = args.lk_cutoff_date {
if let Some(lk_cutoff) = args.opts.lk_cutoff_date {
lk_cutoff_date_opt_string = Some(lk_cutoff.into_string().unwrap())
} else {
lk_cutoff_date_opt_string = None
@ -61,6 +61,7 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
enable_like_kind_treatment: like_kind_election,
lk_cutoff_date_string: like_kind_cutoff_date,
date_separator: date_separator.to_string(),
iso_date_style: args.flags.iso_date
};
let (