Exercise: Luhn Algorithm

The Luhn algorithm is used to validate credit card numbers. The algorithm takes a string as input and does the following to validate the credit card number:

  • Ignore all spaces. Reject numbers with fewer than two digits.
  • Moving from right to left, double every second digit: for the number 1234, we double 3 and 1. For the number 98765, we double 6 and 8.
  • After doubling a digit, sum the digits if the result is greater than 9. So doubling 7 becomes 14 which becomes 1 + 4 = 5.
  • Sum all the undoubled and doubled digits.
  • The credit card number is valid if the sum ends with 0.

The provided code provides a buggy implementation of the luhn algorithm, along with two basic unit tests that confirm that most of the algorithm is implemented correctly.

Copy the code below to <https://play.rust-lang.org/> and write additional tests to uncover bugs in the provided implementation, fixing any bugs you find.

1. ```
   #![allow(unused)]
   ```
2. ```
   fn main() {
   ```
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. ```
    #[cfg(test)]
    ```
26. ```
    mod test {
    ```
27. ```
        use super::*;
    ```

29. ```
        #[test]
    ```
30. ```
        fn test_valid_cc_number() {
    ```
31. ```
            assert!(luhn("4263 9826 4026 9299"));
    ```
32. ```
            assert!(luhn("4539 3195 0343 6467"));
    ```
33. ```
            assert!(luhn("7992 7398 713"));
    ```
34. ```
        }
    ```

36. ```
        #[test]
    ```
37. ```
        fn test_invalid_cc_number() {
    ```
38. ```
            assert!(!luhn("4223 9826 4026 9299"));
    ```
39. ```
            assert!(!luhn("4539 3195 0343 6476"));
    ```
40. ```
            assert!(!luhn("8273 1232 7352 0569"));
    ```
41. ```
        }
    ```
42. ```
    }
    ```
43. ```
    }
    ```