Files
banks2ff/banks2ff/src/core/models.rs

107 lines
3.6 KiB
Rust

use rust_decimal::Decimal;
use chrono::NaiveDate;
use std::fmt;
#[derive(Clone, PartialEq)]
pub struct BankTransaction {
/// Source ID (GoCardless transactionId)
pub internal_id: String,
/// Booking date
pub date: NaiveDate,
/// Amount in account currency
pub amount: Decimal,
/// Account currency code (e.g., EUR)
pub currency: String,
/// Original amount (if currency exchange occurred)
pub foreign_amount: Option<Decimal>,
/// Original currency code
pub foreign_currency: Option<String>,
/// Remittance info or description
pub description: String,
/// Counterparty name
pub counterparty_name: Option<String>,
/// Counterparty IBAN
pub counterparty_iban: Option<String>,
}
impl fmt::Debug for BankTransaction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BankTransaction")
.field("internal_id", &self.internal_id)
.field("date", &self.date)
.field("amount", &"[REDACTED]")
.field("currency", &self.currency)
.field("foreign_amount", &self.foreign_amount.as_ref().map(|_| "[REDACTED]"))
.field("foreign_currency", &self.foreign_currency)
.field("description", &"[REDACTED]")
.field("counterparty_name", &self.counterparty_name.as_ref().map(|_| "[REDACTED]"))
.field("counterparty_iban", &self.counterparty_iban.as_ref().map(|_| "[REDACTED]"))
.finish()
}
}
#[derive(Clone, PartialEq)]
pub struct Account {
pub id: String,
pub iban: String,
pub currency: String,
}
impl fmt::Debug for Account {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Account")
.field("id", &self.id)
.field("iban", &"[REDACTED]")
.field("currency", &self.currency)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use rust_decimal::Decimal;
#[test]
fn test_bank_transaction_debug_masks_sensitive_data() {
let tx = BankTransaction {
internal_id: "test-id".to_string(),
date: NaiveDate::from_ymd_opt(2023, 1, 1).unwrap(),
amount: Decimal::new(12345, 2), // 123.45
currency: "EUR".to_string(),
foreign_amount: Some(Decimal::new(67890, 2)), // 678.90
foreign_currency: Some("USD".to_string()),
description: "Test transaction".to_string(),
counterparty_name: Some("Test Counterparty".to_string()),
counterparty_iban: Some("DE1234567890".to_string()),
};
let debug_str = format!("{:?}", tx);
assert!(debug_str.contains("internal_id"));
assert!(debug_str.contains("date"));
assert!(debug_str.contains("currency"));
assert!(debug_str.contains("foreign_currency"));
assert!(debug_str.contains("[REDACTED]"));
assert!(!debug_str.contains("123.45"));
assert!(!debug_str.contains("678.90"));
assert!(!debug_str.contains("Test transaction"));
assert!(!debug_str.contains("Test Counterparty"));
assert!(!debug_str.contains("DE1234567890"));
}
#[test]
fn test_account_debug_masks_iban() {
let account = Account {
id: "123".to_string(),
iban: "DE1234567890".to_string(),
currency: "EUR".to_string(),
};
let debug_str = format!("{:?}", account);
assert!(debug_str.contains("id"));
assert!(debug_str.contains("currency"));
assert!(debug_str.contains("[REDACTED]"));
assert!(!debug_str.contains("DE1234567890"));
}
}