1use std::str::FromStr;
2use crate::NHSNumber;
3use crate::parse_error::ParseError;
4
5impl FromStr for NHSNumber {
11 type Err = ParseError;
12 fn from_str(s: &str) -> Result<Self, Self::Err> {
13 let chars: Vec<char> = s.chars().collect();
14 if chars.len() < 10 || chars.len() > 13 { return Err(ParseError); } let mut digits: [i8; 10] = [0; 10];
16 let mut i = 0;
17 digits[0] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
18 digits[1] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
19 digits[2] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
20 if chars[i] == ' ' { i += 1; }
21 digits[3] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
22 digits[4] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
23 digits[5] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
24 if chars[i] == ' ' { i += 1; }
25 digits[6] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
26 digits[7] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
27 digits[8] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
28 digits[9] = chars[i].to_digit(10).ok_or(ParseError)? as i8; i += 1;
29 if chars.len() != i { return Err(ParseError); }
30 Ok(NHSNumber { digits: digits })
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_from_str_with_spaces() {
40 let s = String::from("012 345 6789");
41 let actual: NHSNumber = NHSNumber::from_str(&s).unwrap();
42 let expect: NHSNumber = NHSNumber::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
43 assert_eq!(actual, expect);
44 }
45
46 #[test]
47 fn test_from_str_without_spaces() {
48 let s = String::from("0123456789");
49 let actual: NHSNumber = NHSNumber::from_str(&s).unwrap();
50 let expect: NHSNumber = NHSNumber::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
51 assert_eq!(actual, expect);
52 }
53
54 #[test]
55 fn test_from_str_with_wrong_characters() {
56 let s = String::from("012-345-6789");
57 let result: Result<NHSNumber, ParseError> = NHSNumber::from_str(&s);
58 assert!(result.is_err());
59 }
60
61 #[test]
62 fn test_from_str_with_wrong_leading_space() {
63 let s = String::from(" 012 345 6789");
64 let result: Result<NHSNumber, ParseError> = NHSNumber::from_str(&s);
65 assert!(result.is_err());
66 }
67
68 #[test]
69 fn test_from_str_with_wrong_inner_space() {
70 let s = String::from("012 345 6789");
71 let result: Result<NHSNumber, ParseError> = NHSNumber::from_str(&s);
72 assert!(result.is_err());
73 }
74
75 #[test]
76 fn test_from_str_with_wrong_trailing_space() {
77 let s = String::from("012 345 6789 ");
78 let result: Result<NHSNumber, ParseError> = NHSNumber::from_str(&s);
79 assert!(result.is_err());
80 }
81
82 #[test]
83 fn test_from_str_with_wrong_length() {
84 let s = String::from("012");
85 let result: Result<NHSNumber, ParseError> = NHSNumber::from_str(&s);
86 assert!(result.is_err());
87 }
88
89}