use crate::Error; pub struct Transaction { pub date: String, pub payee: String, pub amount: i64, } fn parse_amount_str(amount: &str) -> Result { if amount.is_empty() { return Err(Error::AmountEmpty); } let (whole, frac) = amount.split_once('.').unwrap_or((amount, "00")); let whole = whole.parse::()?; let frac = frac.parse::()?; let mut amount: i64 = 0; amount += whole * 100 * 10; amount += if whole < 0 { -frac } else { frac } * 10; Ok(amount) } impl Transaction { /// Construct a Transaction from [date, payee, amount] strings pub fn from_fields(date: &str, payee: &str, amount: &str) -> Result { Ok(Transaction { date: date.to_owned(), payee: payee.to_owned(), amount: parse_amount_str(amount)?, }) } fn format_amount(&self) -> String { let whole = self.amount / 10 / 100; let frac = if self.amount < 0 { -1 } else { 1 } * (self.amount / 10) % 100; format!("{}.{:02}", whole, frac) } pub fn to_record(&self) -> [String; 4] { [ self.date.to_string(), self.payee.to_string(), String::new(), self.format_amount(), ] } }