psdn-tacsvs/src/main.rs

169 lines
4.7 KiB
Rust
Raw Normal View History

2019-12-22 21:18:45 +00:00
use chrono::naive::NaiveDate;
2019-12-22 21:30:26 +00:00
use std::collections::HashSet;
2019-12-22 21:18:45 +00:00
use string_cache::DefaultAtom;
2019-12-22 21:30:26 +00:00
/// simple typed helper enums
mod simple_enums;
use simple_enums::*;
2019-12-22 21:18:45 +00:00
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum KontoDaten {
None,
2019-12-22 21:30:26 +00:00
Old { knr: u64, blz: u32 },
New { iban: String, bic: String },
2019-12-22 21:18:45 +00:00
}
type TransactionValue = fixed::types::U21F11;
#[derive(Clone, Debug, Eq, PartialEq)]
struct TransactionLine {
d_buchungs: NaiveDate,
d_valuta: NaiveDate,
// ignore 3. column = "Auftraggeber/Zahlungsempfänger",
// because that should be nearly equivalent for every row
p_other: DefaultAtom,
konto_data: KontoDaten,
verwendungszw: String,
kref: String,
waehrung: Waehrung,
umsatz: TransactionValue,
direction: TransactionDirection,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Transactions {
pothc: HashSet<DefaultAtom>,
elems: Vec<TransactionLine>,
}
impl std::ops::Deref for Transactions {
type Target = [TransactionLine];
#[inline]
fn deref(&self) -> &[TransactionLine] {
&self.elems[..]
}
}
impl Transactions {
#[inline]
pub fn new() -> Self {
Default::default()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.elems.is_empty()
}
#[inline]
pub fn len(&self) -> usize {
self.elems.len()
}
pub fn push(&mut self, mut tl: TransactionLine) {
if let Some(x) = self.pothc.get(&tl.p_other) {
tl.p_other = x.clone();
} else {
self.pothc.insert(tl.p_other.clone());
}
self.elems.push(tl);
}
}
2019-12-22 16:55:38 +00:00
fn main() {
use encoding::types::Encoding;
for i in std::env::args().skip(1) {
println!("F = {}", i);
let fh = readfilez::read_from_file(std::fs::File::open(i)).expect("unable to open file");
let dat = encoding::all::ISO_8859_1
.decode(&*fh, encoding::types::DecoderTrap::Replace)
.expect("got invalid latin-1 data");
2019-12-22 21:18:45 +00:00
std::mem::drop(fh);
2019-12-22 16:55:38 +00:00
let mut rdr = csv::ReaderBuilder::new()
.delimiter(b';')
.flexible(true)
.has_headers(false)
.from_reader(dat.as_bytes());
2019-12-22 21:18:45 +00:00
let mut recsit = rdr.records().skip(8);
2019-12-22 21:30:26 +00:00
assert_eq!(
recsit.next().unwrap().unwrap(),
vec![
"Buchungstag",
"Valuta",
"Auftraggeber/Zahlungsempfänger",
"Empfänger/Zahlungspflichtiger",
"Konto-Nr.",
"IBAN",
"BLZ",
"BIC",
"Vorgang/Verwendungszweck",
"Kundenreferenz",
"Währung",
"Umsatz",
" "
]
);
2019-12-22 21:18:45 +00:00
println!("\nData:");
for result in recsit {
2019-12-22 16:55:38 +00:00
let record = result.expect("got invalid line");
2019-12-22 21:18:45 +00:00
assert_eq!(record.len(), 13);
if record[1].is_empty() {
// finalizer line -> ignore
break;
}
// decode KontoDaten
2019-12-22 21:30:26 +00:00
let r_e: &[u8] = &[
record[4].is_empty() as u8,
record[5].is_empty() as u8,
record[6].is_empty() as u8,
record[7].is_empty() as u8,
];
2019-12-22 21:18:45 +00:00
let konto_data = match &*r_e {
&[0, 1, 0, 1] => KontoDaten::Old {
knr: record[4].parse().expect("invalid Konto-Nr."),
blz: record[6].parse().expect("invalid BLZ"),
},
&[1, 0, 1, 0] => KontoDaten::New {
iban: record[5].to_string(),
bic: record[7].to_string(),
},
&[1, 1, 1, 1] => KontoDaten::None,
2019-12-22 21:30:26 +00:00
_ => unimplemented!(
"unsupported KontoData encoding: {:?} :in: {:?}",
&r_e,
&record
),
2019-12-22 21:18:45 +00:00
};
let tl = TransactionLine {
2019-12-22 21:30:26 +00:00
d_buchungs: NaiveDate::parse_from_str(&record[0], "%d.%m.%Y")
.expect("invalid date format"),
d_valuta: NaiveDate::parse_from_str(&record[1], "%d.%m.%Y")
.expect("invalid date format"),
2019-12-22 21:18:45 +00:00
p_other: DefaultAtom::from(&record[3]),
konto_data,
verwendungszw: record[8].to_string(),
kref: record[9].to_string(),
waehrung: record[10].parse().unwrap(),
2019-12-22 21:30:26 +00:00
umsatz: record[11]
.replace('.', "")
.replace(',', ".")
.parse()
.expect("invalid Umsatz"),
2019-12-22 21:18:45 +00:00
direction: record[12].parse().unwrap(),
};
println!("{:?}", tl);
2019-12-22 16:55:38 +00:00
}
}
}