1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
pub struct Details { sort_code: String, account_number: String, weights: Vec<i16>, exceptions: Vec<i8> } fn standard (modulo: i16, details: Details) -> bool { let joined = format!("{}{}", details.sort_code, details.account_number); let result = joined.chars().enumerate().fold(0, |acc, (i, x) | { acc + ((x.to_digit(10).unwrap() as i16) * details.weights[i]) }); let rem = result % modulo; rem == 0 } fn double (modulo: i16, details: Details) -> bool { let joined = format!("{}{}", details.sort_code, details.account_number); let mut result = joined.chars().enumerate().fold(0, |mut acc, (i, x) | { let num = (x.to_digit(10).unwrap() as i16) * details.weights[i]; num.to_string().chars().for_each(|d| { acc = acc + d.to_digit(10).unwrap() as i16 }); acc }); if details.exceptions.contains(&1) { result = result + 27; } println!("dbl {:?}", result); let rem = result % modulo; rem == 0 } pub fn modulus_check(algorithm: &str, details: Details) -> bool { match algorithm { "mod10" => standard(10, details), "mod11" => standard(11, details), "dbl" => double(10, details), _ => { println!("no algorithm"); false } } } #[cfg(test)] mod tests { use super::*; #[test] fn mod10() { assert_eq!(modulus_check("mod10", Details { sort_code: String::from("233142"), account_number: String::from("28937089"), weights: vec![ 2, 1, 2, 1, 2, 1, 30, 36, 24, 20, 16, 12, 8, 4 ], exceptions: vec![] }), true); } #[test] fn dbl() { assert_eq!(modulus_check("dbl", Details { sort_code: String::from("041314"), account_number: String::from("89917189"), weights: vec![ 1, 3, 4, 3, 9, 3, 1, 7, 5, 5, 4, 5, 2, 4 ], exceptions: vec![] }), true); } }