Search code examples
rustnom

Parse a number of a certain size in nom


I can parse a number like this fine:

map_res(digit1, |s: &str| s.parse::<u16>())

but how can I parse a number only if it is within a certain range?


Solution

  • You could check that the parsed number fits in the range and return an error if not:

    map_res(digit1, |s: &str| {
        // uses std::io::Error for brevity, you'd define your own error
        match s.parse::<u16>() {
            Ok(n) if n < MIN || n > MAX => Err(io::Error::new(io::ErrorKind::Other, "out of range")),
            Ok(n) => Ok(n),
            Err(e) => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
        }
    })
    

    The match can also be expressed with the and_then and map_err combinators:

    map_res(digit1, |s: &str| {
        s.parse::<u16>()
            .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))
            .and_then(|n| {
                if n < MIN || n > MAX {
                    Err(io::Error::new(io::ErrorKind::Other, "out of range"))
                } else {
                    Ok(n)
                }
            })
    })