Added error handling. Started with impl Transaction TxType, but it would have been quite verbose to not return more result types in other parts of the code, so did that as well. Resolves #18.

This commit is contained in:
scoobybejesus 2019-08-28 10:05:42 -04:00
parent 71a51e83a7
commit ff52fac130
6 changed files with 46 additions and 41 deletions

View File

@ -5,6 +5,7 @@ use std::rc::{Rc, Weak};
use std::cell::{Cell, RefCell};
use std::fmt;
use std::collections::{HashMap};
use std::error::Error;
use chrono::{NaiveDate, NaiveTime, NaiveDateTime, DateTime, Utc, TimeZone};
use chrono_tz::US::Eastern;
@ -178,19 +179,19 @@ impl Movement {
raw_accts: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>,
)-> d128 {
)-> Result<d128, Box<Error>> {
let txn = txns_map.get(&self.transaction_key).expect("Couldn't get txn. Tx num invalid?");
match txn.transaction_type(ar_map, raw_accts, acct_map) {
match txn.transaction_type(ar_map, raw_accts, acct_map)? {
TxType::Flow => {
let ar = ar_map.get(&self.action_record_key).unwrap();
if ar.direction() == Polarity::Incoming {
self.proceeds.get()
Ok(self.proceeds.get())
}
else { d128!(0) }
else { Ok(d128!(0)) }
}
TxType::Exchange => { d128!(0) }
TxType::ToSelf => { d128!(0) }
TxType::Exchange => { Ok(d128!(0)) }
TxType::ToSelf => { Ok(d128!(0)) }
}
}
@ -200,19 +201,19 @@ impl Movement {
raw_accts: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>,
)-> d128 {
)-> Result<d128, Box<Error>> {
let txn = txns_map.get(&self.transaction_key).expect("Couldn't get txn. Tx num invalid?");
match txn.transaction_type(ar_map, raw_accts, acct_map) {
match txn.transaction_type(ar_map, raw_accts, acct_map)? {
TxType::Flow => {
let ar = ar_map.get(&self.action_record_key).unwrap();
if ar.direction() == Polarity::Outgoing {
self.proceeds.get()
Ok(self.proceeds.get())
}
else { d128!(0) }
else { Ok(d128!(0)) }
}
TxType::Exchange => { d128!(0) }
TxType::ToSelf => { d128!(0) }
TxType::Exchange => { Ok(d128!(0)) }
TxType::ToSelf => { Ok(d128!(0)) }
}
}

View File

@ -49,10 +49,10 @@ pub fn create_lots_and_movements(
let txn_num = num as u32;
let txn = txns_map.get(&(txn_num)).expect("Couldn't get txn. Tx num invalid?");
if txn.marginness(&ar_map, &raw_acct_map, &acct_map) == TxHasMargin::TwoARs {
assert_eq!(txn.transaction_type(&ar_map, &raw_acct_map, &acct_map), TxType::Exchange);
assert_eq!(txn.transaction_type(&ar_map, &raw_acct_map, &acct_map)?, TxType::Exchange);
assert_eq!(txn.action_record_idx_vec.len(), 2);
let the_raw_pair_keys = txn.get_base_and_quote_raw_acct_keys(&ar_map, &raw_acct_map, &acct_map);
let the_raw_pair_keys = txn.get_base_and_quote_raw_acct_keys(&ar_map, &raw_acct_map, &acct_map)?;
let base_acct = acct_map.get(&the_raw_pair_keys.0).expect("Couldn't get acct. Raw pair keys invalid?");
let quote_acct = acct_map.get(&the_raw_pair_keys.1).expect("Couldn't get acct. Raw pair keys invalid?");
@ -217,7 +217,7 @@ pub fn create_lots_and_movements(
}
// Note: a_r is not in home currency if here or below
let polarity = ar.direction();
let tx_type = txn.transaction_type(&ar_map, &raw_acct_map, &acct_map);
let tx_type = txn.transaction_type(&ar_map, &raw_acct_map, &acct_map)?;
match polarity {
Polarity::Outgoing => {
@ -409,7 +409,7 @@ pub fn create_lots_and_movements(
&raw_acct_map,
&acct_map,
&txns_map,
);
)?;
let base_acct = acct_map.get(&base_acct_key).unwrap();
let base_acct_lot = base_acct.list_of_lots.borrow().last().unwrap().clone();
@ -579,7 +579,7 @@ fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx(
raw_acct_map: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>,
) -> (u16, u16) {
) -> Result<(u16, u16), Box<Error>> {
let txn = txns_map.get(&txn_num).expect("Couldn't get txn. Tx num invalid?");
let og_flow_ar = ar_map.get(txn.action_record_idx_vec.first().unwrap()).unwrap();
@ -597,8 +597,8 @@ fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx(
let (base_key,quote_key) = txn_of_og_mvmt_lot_first_mvmt.get_base_and_quote_raw_acct_keys(
ar_map,
&raw_acct_map,
&acct_map); // TODO: should this panic on margin loss?
(base_key, quote_key)
&acct_map)?; // TODO: should this panic on margin loss?
Ok((base_key, quote_key))
}
fn get_base_and_quote_ar_idxs(

View File

@ -4,6 +4,7 @@
use std::fs::File;
use std::collections::{HashMap};
use std::path::PathBuf;
use std::error::Error;
use decimal::d128;
@ -201,7 +202,7 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
raw_acct_map: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>,
) {
) -> Result<(), Box<Error>> {
let mut rows: Vec<Vec<String>> = [].to_vec();
let mut header: Vec<String> = [].to_vec();
@ -230,7 +231,7 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
let txn = txns_map.get(&(txn_num)).unwrap();
let txn_date_string = txn.date.format("%Y/%m/%d").to_string();
let tx_num_string = txn.tx_number.to_string();
let tx_type_string = txn.transaction_type(ars, &raw_acct_map, &acct_map).to_string();
let tx_type_string = txn.transaction_type(ars, &raw_acct_map, &acct_map)?.to_string();
let tx_memo_string = txn.memo.to_string();
let mut term_st: Option<Term> = None;
let mut term_lt: Option<Term> = None;
@ -257,7 +258,7 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
raw_acct_map,
acct_map,
txns_map
);
)?;
for mvmt in flow_or_outgoing_exchange_movements.iter() {
let lot = mvmt.get_lot(acct_map, ars);
@ -294,7 +295,7 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
}
}
if (txn.transaction_type(ars, &raw_acct_map, &acct_map) == TxType::Flow) & (polarity == Some(Polarity::Incoming)) {
if (txn.transaction_type(ars, &raw_acct_map, &acct_map)? == TxType::Flow) & (polarity == Some(Polarity::Incoming)) {
// println!("Incoming flow {}", txn.tx_number);
income_st = proceeds_st;
proceeds_st = d128!(0);
@ -304,7 +305,7 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
cost_basis_lt = d128!(0);
}
if (txn.transaction_type(ars, &raw_acct_map, &acct_map) == TxType::Flow) & (polarity == Some(Polarity::Outgoing)) {
if (txn.transaction_type(ars, &raw_acct_map, &acct_map)? == TxType::Flow) & (polarity == Some(Polarity::Outgoing)) {
// println!("Outgoing flow {}, proceeds_st {}, proceeds_lt {}", txn.tx_number, proceeds_st, proceeds_lt);
expense_st -= proceeds_st;
expense_lt -= proceeds_lt;
@ -361,6 +362,8 @@ pub fn _5_transaction_mvmt_summaries_to_csv(
wtr.write_record(row).expect("Could not write row to CSV file");
}
wtr.flush().expect("Could not flush Writer, though file should exist and be complete");
Ok(())
}
// pub fn accounts_to_csv(

View File

@ -37,7 +37,7 @@ pub fn add_cost_basis_to_movements(
for mvmt in movements.iter() {
let polarity = ar.direction();
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map);
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
let is_home_curr = raw_acct.is_home_currency(&settings.home_currency);
let mvmt_copy = mvmt.clone();
let borrowed_mvmt = mvmt_copy.clone();
@ -169,7 +169,7 @@ pub fn add_proceeds_to_movements(
for mvmt in movements.iter() {
let polarity = ar.direction();
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map);
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
let mvmt_copy = mvmt.clone();
let borrowed_mvmt = mvmt_copy.clone();
@ -249,7 +249,7 @@ fn update_current_txn_for_prior_likekind_treatment(
for mvmt in movements.iter() {
let polarity = ar.direction();
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map);
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
let is_home_curr = raw_acct.is_home_currency(&settings.home_currency);
let mvmt_copy = mvmt.clone();
@ -303,7 +303,7 @@ fn perform_likekind_treatment_on_txn(
) -> Result<(), Box<Error>> {
let txn = txns_map.get(&txn_num).unwrap();
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map);
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
let og_ar = ars.get(&txn.action_record_idx_vec.first().unwrap()).unwrap();
let ic_ar = ars.get(&txn.action_record_idx_vec.last().unwrap()).unwrap();

View File

@ -291,7 +291,7 @@ fn main() -> Result<(), Box<dyn Error>> {
&raw_acct_map,
&account_map,
&transactions_map
);
)?;
}

View File

@ -6,6 +6,7 @@ use std::cell::{RefCell};
use std::process::exit;
use std::fmt;
use std::collections::{HashMap};
use std::error::Error;
use decimal::d128;
use chrono::NaiveDate;
@ -30,10 +31,10 @@ impl Transaction {
ars: &HashMap<u32, ActionRecord>,
raw_acct_map: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
) -> TxType {
) -> Result<TxType, Box<Error>> {
if self.action_record_idx_vec.len() == 1 {
TxType::Flow
Ok(TxType::Flow)
}
else if self.action_record_idx_vec.len() == 2 {
// This exercise of splitting the strings is because of margin accounts, where BTC borrowed to buy XMR would reflect as BTC_xmr
@ -55,14 +56,14 @@ impl Transaction {
}
if ar1_ticker == ar2_ticker {
if ar1_raw_acct.is_margin != ar2_raw_acct.is_margin {
TxType::Flow
Ok(TxType::Flow)
}
else {
TxType::ToSelf
Ok(TxType::ToSelf)
}
}
else {
TxType::Exchange
Ok(TxType::Exchange)
}
}
else if self.action_record_idx_vec.len() > 2 {
@ -111,9 +112,9 @@ impl Transaction {
ars: &HashMap<u32, ActionRecord>,
raw_accts: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>
) -> (u16, u16) {
) -> Result<(u16, u16), Box<Error>> {
assert_eq!(self.transaction_type(ars, raw_accts, acct_map), TxType::Exchange,
assert_eq!(self.transaction_type(ars, raw_accts, acct_map)?, TxType::Exchange,
"This can only be called on exchange transactions.");
let first_ar = ars.get(&self.action_record_idx_vec[0]).unwrap();
@ -134,11 +135,11 @@ impl Transaction {
if first_raw_acct.ticker.contains('_') {
quote = first_acct_raw_key;
base = second_acct_raw_key;
(base, quote)
Ok((base, quote))
} else if second_raw_acct.ticker.contains('_') {
base = first_acct_raw_key;
quote = second_acct_raw_key;
(base, quote)
Ok((base, quote))
} else {
println!("{}", VariousErrors::MarginNoUnderbar); use std::process::exit; exit(1)
}
@ -151,7 +152,7 @@ impl Transaction {
raw_acct_map: &HashMap<u16, RawAccount>,
acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>,
) -> Vec<Rc<Movement>> {
) -> Result<Vec<Rc<Movement>>, Box<Error>> {
let mut flow_or_outgoing_exchange_movements = [].to_vec();
@ -165,7 +166,7 @@ impl Transaction {
let movements = ar.get_mvmts_in_ar(acct_map, txns_map);
match self.transaction_type(ars, raw_acct_map, acct_map) {
match self.transaction_type(ars, raw_acct_map, acct_map)? {
TxType::Exchange => {
if Polarity::Outgoing == ar.direction() {
for mvmt in movements.iter() {
@ -182,7 +183,7 @@ impl Transaction {
}
}
}
flow_or_outgoing_exchange_movements
Ok(flow_or_outgoing_exchange_movements)
}
}