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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
pub mod error;
pub use self::error::{Error, Result};
use regex::Regex;
lazy_static! {
static ref ALPHANUM: Regex = Regex::new(r"^[a-zA-Z0-9_-]+$").unwrap();
static ref NUMTEXT: Regex = Regex::new(r"^[0-9]+$").unwrap();
}
pub fn currency(f: f64) -> Result<f64> {
if f <= 0.0 {
return Err(Error::InvalidAmount);
}
let precise_round = format!("{:.2}", f).parse::<f64>();
Ok(precise_round.unwrap())
}
pub fn alphanumeric(s: &str) -> Result<()> {
regex(&ALPHANUM, s, Error::NotAlphaNumeric(s.to_owned()))
}
pub fn numtext(s: &str) -> Result<()> {
regex(&NUMTEXT, s, Error::NotNumeric(s.to_owned()))
}
pub fn regex(reg: &Regex, s: &str, error: Error) -> Result<()> {
if reg.is_match(s) {
Ok(())
} else {
Err(error)
}
}
pub fn length(s: &str, min: i32, max: i32) -> Result<()> {
let len = s.len();
if min as usize <= len && len <= max as usize {
Ok(())
} else {
Err(Error::Length(s.to_owned(), min as usize, max as usize))
}
}
pub fn luhn10(s: &str) -> Result<()> {
try!(numtext(s));
let mut digits = s.rsplit("").filter_map(|ch| {
if ch.is_empty() {
None
} else {
Some(ch.parse::<i8>().unwrap())
}
});
let mut alt = false;
let mut sum = 0;
for digit in &mut digits {
let mut luhn = digit;
if alt {
luhn *= 2;
if luhn > 9 { luhn -= 9; }
}
sum += luhn;
alt = !alt;
}
if sum % 10 == 0 && !s.is_empty() {
Ok(())
} else {
Err(Error::NotLuhn10(s.to_owned()))
}
}