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:
parent
8567dd04b0
commit
7002923a4c
|
@ -53,6 +53,7 @@ pub struct ImportProcessParameters {
|
||||||
pub costing_method: InventoryCostingMethod,
|
pub costing_method: InventoryCostingMethod,
|
||||||
pub lk_cutoff_date_string: String,
|
pub lk_cutoff_date_string: String,
|
||||||
pub date_separator: String,
|
pub date_separator: String,
|
||||||
|
pub iso_date_style: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn import_and_process_final(
|
pub(crate) fn import_and_process_final(
|
||||||
|
@ -79,6 +80,7 @@ pub(crate) fn import_and_process_final(
|
||||||
&mut raw_account_map,
|
&mut raw_account_map,
|
||||||
&mut account_map,
|
&mut account_map,
|
||||||
&settings.date_separator,
|
&settings.date_separator,
|
||||||
|
settings.iso_date_style,
|
||||||
) {
|
) {
|
||||||
Ok(()) => { println!("Successfully imported csv file."); }
|
Ok(()) => { println!("Successfully imported csv file."); }
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -96,6 +98,7 @@ pub(crate) fn import_and_process_final(
|
||||||
raw_acct_map: &mut HashMap<u16, RawAccount>,
|
raw_acct_map: &mut HashMap<u16, RawAccount>,
|
||||||
acct_map: &mut HashMap<u16, Account>,
|
acct_map: &mut HashMap<u16, Account>,
|
||||||
date_separator: &str,
|
date_separator: &str,
|
||||||
|
iso_date_style: bool,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let file = File::open(import_file_path)?; println!("CSV ledger file opened successfully.\n");
|
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,
|
transactions_map,
|
||||||
action_records,
|
action_records,
|
||||||
date_separator,
|
date_separator,
|
||||||
|
iso_date_style,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -112,6 +112,7 @@ pub(crate) fn import_transactions(
|
||||||
txns_map: &mut HashMap<u32, Transaction>,
|
txns_map: &mut HashMap<u32, Transaction>,
|
||||||
action_records: &mut HashMap<u32, ActionRecord>,
|
action_records: &mut HashMap<u32, ActionRecord>,
|
||||||
sep: &str,
|
sep: &str,
|
||||||
|
iso: bool,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let mut this_tx_number = 0;
|
let mut this_tx_number = 0;
|
||||||
|
@ -200,11 +201,19 @@ pub(crate) fn import_transactions(
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let format_yy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%y");
|
let format_yy: String;
|
||||||
let format_yyyy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%Y");
|
let format_yyyy: String;
|
||||||
|
|
||||||
let tx_date = NaiveDate::parse_from_str(this_tx_date, format_yy)
|
if iso {
|
||||||
.unwrap_or(NaiveDate::parse_from_str(this_tx_date, format_yyyy)
|
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")
|
.expect("\nFailed to parse date in input file. Check date separator character. Also %m/%d/%y (or %Y) format is required.\n")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
56
src/main.rs
56
src/main.rs
|
@ -36,19 +36,48 @@ pub(crate) struct Cli {
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
|
|
||||||
|
#[structopt(flatten)]
|
||||||
|
opts: Options,
|
||||||
|
|
||||||
/// File to be imported. (Currently, the only supported date format is %m/%d/%y.)
|
/// File to be imported. (Currently, the only supported date format is %m/%d/%y.)
|
||||||
#[structopt(name = "file", parse(from_os_str))]
|
#[structopt(name = "file", parse(from_os_str))]
|
||||||
file_to_import: Option<PathBuf>,
|
file_to_import: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Output directory for exported reports.
|
#[derive(StructOpt, Debug)]
|
||||||
#[structopt(name = "output directory", short, long = "output", default_value = ".", parse(from_os_str))]
|
pub(crate) struct Flags {
|
||||||
output_dir_path: PathBuf,
|
|
||||||
|
/// 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
|
/// 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).
|
/// 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))]
|
#[structopt(name = "date separator character", short, long = "date-separator", default_value = "h", parse(from_os_str))]
|
||||||
date_separator: OsString,
|
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.
|
/// 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.
|
/// 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))]
|
#[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,
|
inv_costing_method: OsString,
|
||||||
|
|
||||||
/// Home currency (currency in which all resulting reports are denominated).
|
/// Output directory for exported reports.
|
||||||
/// (Only available as a command line setting.)
|
#[structopt(name = "output directory", short, long = "output", default_value = ".", parse(from_os_str))]
|
||||||
#[structopt(name = "home currency", short = "c", long = "currency", default_value = "USD", parse(from_os_str))]
|
output_dir_path: PathBuf,
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
|
||||||
bool
|
bool
|
||||||
), Box<dyn Error>> {
|
), 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" => {"-"}
|
"h" => {"-"}
|
||||||
"s" => {"/"}
|
"s" => {"/"}
|
||||||
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
|
_ => { 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()?;
|
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_election;
|
||||||
let like_kind_cutoff_date_string: String;
|
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_election = true;
|
||||||
like_kind_cutoff_date_string = date.into_string().unwrap();
|
like_kind_cutoff_date_string = date.into_string().unwrap();
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,6 +59,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
|
||||||
enable_like_kind_treatment: like_kind_election,
|
enable_like_kind_treatment: like_kind_election,
|
||||||
lk_cutoff_date_string: like_kind_cutoff_date_string,
|
lk_cutoff_date_string: like_kind_cutoff_date_string,
|
||||||
date_separator: date_separator.to_string(),
|
date_separator: date_separator.to_string(),
|
||||||
|
iso_date_style: args.flags.iso_date
|
||||||
};
|
};
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
|
||||||
|
|
||||||
shall_we_proceed()?;
|
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" => {"-"}
|
"h" => {"-"}
|
||||||
"s" => {"/"}
|
"s" => {"/"}
|
||||||
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
|
_ => { 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()?;
|
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;
|
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())
|
lk_cutoff_date_opt_string = Some(lk_cutoff.into_string().unwrap())
|
||||||
} else {
|
} else {
|
||||||
lk_cutoff_date_opt_string = None
|
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,
|
enable_like_kind_treatment: like_kind_election,
|
||||||
lk_cutoff_date_string: like_kind_cutoff_date,
|
lk_cutoff_date_string: like_kind_cutoff_date,
|
||||||
date_separator: date_separator.to_string(),
|
date_separator: date_separator.to_string(),
|
||||||
|
iso_date_style: args.flags.iso_date
|
||||||
};
|
};
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|
Loading…
Reference in New Issue