#![allow(dead_code)]
use std::fmt::Display;
use std::str::FromStr;
#[derive(Clone, PartialEq)]
pub struct Iban {
pub iban: String,
}
impl FromStr for Iban {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self { iban: s.to_owned() })
}
}
impl Display for Iban {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.iban)
}
}
#[derive(Debug)]
pub enum IbanError {
FalutyPrefix,
FaultyAccount,
FaultyBank,
InvalidCheckSum,
InvalidFormat,
}
impl Iban {
pub fn new_cz(prefix: Option<&str>, account: &str, bank: &str) -> Result<Self, IbanError> {
let country_code = "CZ"; let country_code_num = "1235"; let prefix = prefix.unwrap_or("000000");
let full_account = format!("{prefix}{account}"); let checksum_prep =
match format!("{}{}{}00", bank, full_account, country_code_num).parse::<u128>() {
Ok(x) => x,
_ => return Err(IbanError::InvalidFormat),
};
let modulo = checksum_prep % 97;
let checksum = 98 - modulo;
let iban = format!("{}{}{}{}", country_code, checksum, bank, full_account);
Ok(Self { iban })
}
}
#[test]
fn filips_account_is_calculated_correctly() {
let iban = Iban::new_cz(Some("000019"), "0000123457", "0710").unwrap();
assert_eq!(iban.to_string(), "CZ3507100000190000123457".to_owned())
}