1. ```
// This is the buggy version that appears in the problem.
```
2. ```
#[cfg(never)]
```
3. ```
pub fn luhn(cc_number: &str) -> bool {
```
4. ```
let mut sum = 0;
```
5. ```
let mut double = false;
```
7. ```
for c in cc_number.chars().rev() {
```
8. ```
if let Some(digit) = c.to_digit(10) {
```
9. ```
if double {
```
10. ```
let double_digit = digit * 2;
```
11. ```
sum +=
```
12. ```
if double_digit > 9 { double_digit - 9 } else { double_digit };
```
13. ```
} else {
```
14. ```
sum += digit;
```
15. ```
}
```
16. ```
double = !double;
```
17. ```
} else {
```
18. ```
continue;
```
19. ```
}
```
20. ```
}
```
22. ```
sum % 10 == 0
```
23. ```
}
```
25. ```
// This is the solution and passes all of the tests below.
```
26. ```
pub fn luhn(cc_number: &str) -> bool {
```
27. ```
let mut sum = 0;
```
28. ```
let mut double = false;
```
29. ```
let mut digits = 0;
```
31. ```
for c in cc_number.chars().rev() {
```
32. ```
if let Some(digit) = c.to_digit(10) {
```
33. ```
digits += 1;
```
34. ```
if double {
```
35. ```
let double_digit = digit * 2;
```
36. ```
sum +=
```
37. ```
if double_digit > 9 { double_digit - 9 } else { double_digit };
```
38. ```
} else {
```
39. ```
sum += digit;
```
40. ```
}
```
41. ```
double = !double;
```
42. ```
} else if c.is_whitespace() {
```
43. ```
// New: accept whitespace.
```
44. ```
continue;
```
45. ```
} else {
```
46. ```
// New: reject all other characters.
```
47. ```
return false;
```
48. ```
}
```
49. ```
}
```
51. ```
// New: check that we have at least two digits
```
52. ```
digits >= 2 && sum % 10 == 0
```
53. ```
}
```
55. ```
fn main() {
```
56. ```
let cc_number = "1234 5678 1234 5670";
```
57. ```
println!(
```
58. ```
"Is {cc_number} a valid credit card number? {}",
```
59. ```
if luhn(cc_number) { "yes" } else { "no" }
```
60. ```
);
```
61. ```
}
```
63. ```
#[cfg(test)]
```
64. ```
mod test {
```
65. ```
use super::*;
```
67. ```
#[test]
```
68. ```
fn test_valid_cc_number() {
```
69. ```
assert!(luhn("4263 9826 4026 9299"));
```
70. ```
assert!(luhn("4539 3195 0343 6467"));
```
71. ```
assert!(luhn("7992 7398 713"));
```
72. ```
}
```
74. ```
#[test]
```
75. ```
fn test_invalid_cc_number() {
```
76. ```
assert!(!luhn("4223 9826 4026 9299"));
```
77. ```
assert!(!luhn("4539 3195 0343 6476"));
```
78. ```
assert!(!luhn("8273 1232 7352 0569"));
```
79. ```
}
```
81. ```
#[test]
```
82. ```
fn test_non_digit_cc_number() {
```
83. ```
assert!(!luhn("foo"));
```
84. ```
assert!(!luhn("foo 0 0"));
```
85. ```
}
```
87. ```
#[test]
```
88. ```
fn test_empty_cc_number() {
```
89. ```
assert!(!luhn(""));
```
90. ```
assert!(!luhn(" "));
```
91. ```
assert!(!luhn(" "));
```
92. ```
assert!(!luhn(" "));
```
93. ```
}
```
95. ```
#[test]
```
96. ```
fn test_single_digit_cc_number() {
```
97. ```
assert!(!luhn("0"));
```
98. ```
}
```
100. ```
#[test]
```
101. ```
fn test_two_digit_cc_number() {
```
102. ```
assert!(luhn(" 0 0 "));
```
103. ```
}
```
104. ```
}
```