use std::collections::HashMap;
#[derive(Debug, Default)]
#[allow(dead_code)]
pub struct SepaTransaction {
pub transaction_type: Option<String>,
pub creditor_scheme_identifier: Option<String>,
pub creditor_name: Option<String>,
pub mandate_reference: Option<String>,
pub remittance_info: Option<String>,
pub iban: Option<String>,
pub bic: Option<String>,
pub reference: Option<String>,
}
impl SepaTransaction {
pub fn parse(raw_desc: &str) -> Self {
let tags = [
"/TRTP/", "/CSID/", "/NAME/", "/MARF/", "/REMI/", "/IBAN/", "/BIC/", "/EREF/",
];
let mut extracted_data: HashMap<&str, String> = HashMap::new();
let mut positions: Vec<(&str, usize)> = tags
.iter()
.filter_map(|&tag| raw_desc.find(tag).map(|idx| (tag, idx)))
.collect();
positions.sort_by_key(|&(_, idx)| idx);
for i in 0..positions.len() {
let (current_tag, current_idx) = positions[i];
let start_value_idx = current_idx + current_tag.len();
let end_value_idx = if i + 1 < positions.len() {
positions[i + 1].1
} else {
raw_desc.len()
};
let value = raw_desc[start_value_idx..end_value_idx].trim().to_string();
extracted_data.insert(current_tag, value);
}
SepaTransaction {
transaction_type: extracted_data.remove("/TRTP/"),
creditor_scheme_identifier: extracted_data.remove("/CSID/"),
creditor_name: extracted_data.remove("/NAME/"),
mandate_reference: extracted_data.remove("/MARF/"),
remittance_info: extracted_data.remove("/REMI/"),
iban: extracted_data.remove("/IBAN/"),
bic: extracted_data.remove("/BIC/"),
reference: extracted_data.remove("/EREF/"),
}
}
}
pub fn abnamro_clean_description(input: &str) -> String {
let mut result = String::with_capacity(input.len() + input.len() / 32);
let mut last_was_space = false;
for (count, c) in input.chars().enumerate() {
if count > 0 && count % 32 == 0 && !last_was_space {
result.push(' ');
last_was_space = true;
}
if c == ' ' {
if !last_was_space {
result.push(c);
last_was_space = true;
}
} else {
result.push(c);
last_was_space = false;
}
}
result
}