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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
#[allow(dead_code)]
mod fizzbuzz
{
    pub fn is_fizz(n: i32) -> bool
    {
        n.abs() % 3 == 0 && !is_fizzbuzz(n)
    }

    pub fn is_buzz(n: i32) -> bool
    {
        n.abs() % 5 == 0 && !is_fizzbuzz(n)
    }

    pub fn is_fizzbuzz(n: i32) -> bool
    {
        n.abs() % 15 == 0
    }

    pub fn is_none(n: i32) -> bool
    {
        !is_fizz(n) && !is_buzz(n) && !is_fizzbuzz(n)
    }

    pub fn check(n: i32) -> String
    {
        if is_fizzbuzz(n)
        {
            return "fizzbuzz".to_string();
        }

        if is_fizz(n)
        {
            return "fizz".to_string();
        }

        if is_buzz(n)
        {
            return "buzz".to_string();
        }

        n.to_string()
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn detects_fizz()
    {
        assert!(fizzbuzz::is_fizz(3));
        assert!(fizzbuzz::is_fizz(6));
        assert!(!fizzbuzz::is_fizz(15));
    }

    #[test]
    fn detects_buzz()
    {
        assert!(fizzbuzz::is_buzz(5));
        assert!(fizzbuzz::is_buzz(10));
        assert!(!fizzbuzz::is_buzz(15));
    }

    #[test]
    fn detects_fizzbuzz()
    {
        assert!(fizzbuzz::is_fizzbuzz(15));
        assert!(fizzbuzz::is_fizzbuzz(30));
        assert!(!fizzbuzz::is_fizzbuzz(33));
    }

    #[test]
    fn detects_none()
    {
        assert!(fizzbuzz::is_none(17));
        assert!(!fizzbuzz::is_none(3));
        assert!(!fizzbuzz::is_none(5));
        assert!(!fizzbuzz::is_none(15));
    }

    #[test]
    fn checks_from_negative_30_to_positive_30()
    {
        let expected = vec![
            "fizzbuzz", "-29", "-28", "fizz", "-26", "buzz", "fizz", "-23", "-22", "fizz",
            "buzz", "-19", "fizz", "-17", "-16", "fizzbuzz", "-14", "-13", "fizz", "-11",
            "buzz", "fizz", "-8", "-7", "fizz", "buzz", "-4", "fizz", "-2", "-1",
            "fizzbuzz", // 0
            "1", "2", "fizz", "4", "buzz", "fizz", "7", "8", "fizz", "buzz",
            "11", "fizz", "13", "14", "fizzbuzz", "16", "17", "fizz", "19", "buzz",
            "fizz", "22", "23", "fizz", "buzz", "26", "fizz", "28", "29", "fizzbuzz",
        ];

        let mut results: Vec<String> = vec![];

        for n in -30..=30
        {
            results.push(fizzbuzz::check(n));
        }

        assert_eq!(results, expected);
    }
}