1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
use crate::model::Transaction;
use chrono::NaiveDate;
pub fn parse(filename: &str) -> anyhow::Result<Vec<Transaction>> {
let file = std::fs::File::open(filename)?;
let mut reader = csv::ReaderBuilder::new()
.has_headers(true)
.from_reader(file);
let mut transactions = Vec::new();
for result in reader.records() {
let record = result?;
if record.len() >= 5 {
// Format: "date","transaction","description","amount","balance"
if let (Ok(date), Some(description), Ok(amount)) = (
NaiveDate::parse_from_str(&record[0], "%Y-%m-%d"),
record.get(2),
record[3].parse::<f64>(),
) {
let account = "Wise".to_string();
transactions.push(Transaction::new(
date,
description.to_string(),
amount,
account,
));
}
}
}
Ok(transactions)
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn test_wise_parser() {
let csv_content = "\"date\",\"transaction\",\"description\",\"amount\",\"balance\"\n\"2025-05-18\",\"TRFIN\",\"Money transfer into the account (executed at 2025-05-18), FX Rate: 1.3843\",\"112239.94\",\"112239.94\"\n\"2025-05-18\",\"TRFOUT\",\"Money transfer out of the account (executed at 2025-05-18)\",\"-100000.0\",\"12239.94\"";
let mut temp_file = NamedTempFile::new().unwrap();
temp_file.write_all(csv_content.as_bytes()).unwrap();
temp_file.flush().unwrap();
let transactions = parse(temp_file.path().to_str().unwrap()).unwrap();
assert_eq!(transactions.len(), 2);
let first_txn = &transactions[0];
assert_eq!(first_txn.date.format("%Y-%m-%d").to_string(), "2025-05-18");
assert_eq!(
first_txn.description,
"Money transfer into the account (executed at 2025-05-18), FX Rate: 1.3843"
);
assert_eq!(first_txn.amount, 112239.94);
assert_eq!(first_txn.account, "Wise");
assert_eq!(first_txn.category, Some("Transfer".to_string()));
let second_txn = &transactions[1];
assert_eq!(second_txn.date.format("%Y-%m-%d").to_string(), "2025-05-18");
assert_eq!(
second_txn.description,
"Money transfer out of the account (executed at 2025-05-18)"
);
assert_eq!(second_txn.amount, -100000.0);
assert_eq!(second_txn.account, "Wise");
assert_eq!(second_txn.category, Some("Transfer".to_string()));
}
}
|