70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
use crate::simple_enums::{TransactionDirection, Waehrung};
|
|
use chrono::naive::NaiveDate;
|
|
use serde::{Deserialize, Serialize};
|
|
use thiserror::Error;
|
|
|
|
pub type TransactionValue = fixed::types::U53F11;
|
|
|
|
#[derive(Clone, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
|
pub struct TransactionLine {
|
|
pub d_buchungs: NaiveDate,
|
|
pub d_valuta: NaiveDate,
|
|
// ignore 3. column = "Auftraggeber/Zahlungsempfänger",
|
|
// because that should be nearly equivalent for every row
|
|
pub p_other: String,
|
|
// ignore KontoData, it's unreliable
|
|
pub verwendungszw: String,
|
|
// ignore 10. column = "Kundenreferenz"
|
|
// should be almost always empty
|
|
pub waehrung: Waehrung,
|
|
pub umsatz: TransactionValue,
|
|
pub direction: TransactionDirection,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Error)]
|
|
pub enum ParseError {
|
|
#[error("invalid date")]
|
|
Chrono(#[from] chrono::format::ParseError),
|
|
|
|
#[error("invalid H/S")]
|
|
Direction(#[from] crate::simple_enums::parser_error::TransactionDirection),
|
|
|
|
#[error("finalizer line")]
|
|
Finalizer,
|
|
|
|
#[error("invalid fixed-point number")]
|
|
Fixed(#[from] fixed::ParseFixedError),
|
|
|
|
#[error("invalid integer")]
|
|
Integer(#[from] std::num::ParseIntError),
|
|
|
|
#[error("invalid currency")]
|
|
Waehrung(#[from] crate::simple_enums::parser_error::Waehrung),
|
|
}
|
|
|
|
impl std::convert::TryFrom<csv::StringRecord> for TransactionLine {
|
|
type Error = ParseError;
|
|
|
|
fn try_from(record: csv::StringRecord) -> Result<Self, ParseError> {
|
|
assert_eq!(record.len(), 13);
|
|
if record[1].is_empty() {
|
|
// finalizer line
|
|
return Err(ParseError::Finalizer);
|
|
}
|
|
|
|
// no "Kundenreferenz"
|
|
assert!(record[9].is_empty());
|
|
|
|
// assemble
|
|
Ok(TransactionLine {
|
|
d_buchungs: NaiveDate::parse_from_str(&record[0], "%d.%m.%Y")?,
|
|
d_valuta: NaiveDate::parse_from_str(&record[1], "%d.%m.%Y")?,
|
|
p_other: record[3].to_string(),
|
|
verwendungszw: record[8].to_string(),
|
|
waehrung: record[10].parse()?,
|
|
umsatz: record[11].replace('.', "").replace(',', ".").parse()?,
|
|
direction: record[12].parse()?,
|
|
})
|
|
}
|
|
}
|