48 lines
1.3 KiB
Rust
48 lines
1.3 KiB
Rust
use crate::Error;
|
|
|
|
pub struct Transaction {
|
|
pub date: String,
|
|
pub payee: String,
|
|
pub amount: i64,
|
|
}
|
|
|
|
fn parse_amount_str(amount: &str) -> Result<i64, Error> {
|
|
if amount.is_empty() {
|
|
return Err(Error::AmountEmpty);
|
|
}
|
|
let (whole, frac) = amount.split_once('.').unwrap_or((amount, "00"));
|
|
let whole = whole.parse::<i64>()?;
|
|
let frac = frac.parse::<i64>()?;
|
|
|
|
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<Transaction, Error> {
|
|
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(),
|
|
]
|
|
}
|
|
}
|