codes_check_digits/
error.rs1use codes_common::CodeParseError;
8use std::{
9 fmt::{Debug, Display},
10 ops::RangeInclusive,
11};
12use tracing::warn;
13
14#[derive(Clone, Debug, PartialEq, Eq)]
22pub enum CheckDigitError {
23 InvalidLength { min: usize, max: usize, got: usize },
25 InvalidAlphabet { alphabet: String },
27 InvalidCheckDigit { expecting: String, got: String },
29}
30
31pub type Result<T> = std::result::Result<T, CheckDigitError>;
35
36pub fn invalid_length(expecting: RangeInclusive<usize>, got: usize) -> CheckDigitError {
41 warn!("Invalid input length, {} not in {:?}", got, expecting);
42 CheckDigitError::InvalidLength {
43 min: *expecting.start(),
44 max: *expecting.end(),
45 got,
46 }
47}
48
49pub fn invalid_alphabet<S>(alphabet: S) -> CheckDigitError
50where
51 S: Into<String>,
52{
53 let alphabet = alphabet.into();
54 warn!(
55 "One or more input characters not in the alphabet {}",
56 alphabet
57 );
58 CheckDigitError::InvalidAlphabet { alphabet }
59}
60
61pub fn invalid_check_digit<T1, T2>(expecting: T1, got: T2) -> CheckDigitError
62where
63 T1: Display,
64 T2: Display,
65{
66 warn!("Invalid check digit expecting {}, got {}", expecting, got);
67 CheckDigitError::InvalidCheckDigit {
68 expecting: expecting.to_string(),
69 got: got.to_string(),
70 }
71}
72
73impl Display for CheckDigitError {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(
80 f,
81 "{}",
82 match self {
83 CheckDigitError::InvalidLength { min, max, got } => format!(
84 "Expecting input length in the range {}..={}, not {}",
85 min, max, got
86 ),
87 CheckDigitError::InvalidAlphabet { alphabet } =>
88 format!("Expecting characters from the alphabet {:?}", alphabet),
89 CheckDigitError::InvalidCheckDigit { expecting, got } => format!(
90 "Invalid check digit in string, expecting {}, got {}",
91 expecting, got
92 ),
93 }
94 )
95 }
96}
97
98impl std::error::Error for CheckDigitError {}
99
100impl From<CheckDigitError> for CodeParseError {
101 fn from(e: CheckDigitError) -> Self {
102 Self::CheckDigit(Box::new(e))
103 }
104}