use crate::secondary_validation::Validator;
pub struct BulgarianEGNChecksum;
const BULGARIAN_EGN_MULTIPLIERS: [u32; 9] = [2, 4, 8, 5, 10, 9, 7, 3, 6];
impl Validator for BulgarianEGNChecksum {
fn is_valid_match(&self, regex_match: &str) -> bool {
let mut chars = regex_match.chars().filter_map(|c| c.to_digit(10));
let mut sum = 0;
for w in BULGARIAN_EGN_MULTIPLIERS.iter() {
match chars.next() {
Some(digit) => sum += digit * w,
None => return false,
}
}
let mut expected_check_digit = sum % 11;
if expected_check_digit == 10 {
expected_check_digit = 0;
}
match chars.next() {
Some(actual_check_digit) => actual_check_digit == expected_check_digit,
None => false,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_valid_egn() {
let valid_egns = [
"7523169263", "8032056031", "6101057509", "8001010008", ];
let validator = BulgarianEGNChecksum;
for egn in &valid_egns {
assert!(validator.is_valid_match(egn), "EGN should be valid: {egn}");
}
}
#[test]
fn test_invalid_egn() {
let invalid_egns = [
"7523169264", "8032056032", "6101057500", "8001010000", ];
let validator = BulgarianEGNChecksum;
for egn in &invalid_egns {
assert!(
!validator.is_valid_match(egn),
"EGN should be invalid: {egn}"
);
}
}
}