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
use std::str::FromStr;

/// Like the c function atoi, trim space and tabs at the beginning of the string
/// and then parse to the T integer type the following number chars.
///
/// Return an error the first non space char is different from a number.
pub fn atoi<T>(s: &str) -> Result<T, &'static str>
    where T: FromStr
{
    let mut number_has_began = false;
    let mut nbr_str = String::new();

    for c in s.chars() {
        if !number_has_began && c.is_numeric() {
            number_has_began = true;
        }
        if number_has_began {
            if c.is_numeric() {
                nbr_str.push(c);
            } else {
                break;
            }
        }
    }

    if nbr_str.len() > 0 {
        Ok(nbr_str.parse::<T>().ok().unwrap())
    } else {
        Err("Cannot parse the string to integer")
    }
}



#[cfg(test)]
mod test {
    use super::*;

    fn one_atoi_test(s: &str, expected: i32) {
        let nbr: i32 = atoi(s).unwrap();
        assert!(nbr == expected);
    }

    #[test]
    fn test_atoi() {
        one_atoi_test("5", 5);
        one_atoi_test("20", 20);
        one_atoi_test("555", 555);
        one_atoi_test("    555", 555);
        one_atoi_test("    555pppp", 555);
    }

    #[test]
    #[should_panic]
    fn test_atoi2() {
        one_atoi_test("", 5);
    }

    #[test]
    #[should_panic]
    fn test_atoi3() {
        one_atoi_test("aaa", 5);
    }
}