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?
You can use the verify convenience combinator. Like so:
fn parse_u16_clamped(i: &str, min: u16, max: u16) -> IResult<&str, u16> {
let number = map_res(digit1, |s: &str| s.parse::<u16>());
verify(number, |n| n < max && n > min)(i)
}
Since ErrorKind::Other
does not occur in Nom 7, you can also add context()
to a VerboseError
:
fn parse_range<T: FromStr + PartialOrd>(
s: &str,
r: Range<T>,
) -> IResult<&str, T, VerboseError<&str>> {
let (s2, n) = map_res(digit1, |digits: &str| digits.parse::<T>())(s)?;
if !r.contains(&n) {
context("out of range", fail)(s)
} else {
Ok((s2, n))
}
}
You could check that the parsed number fits in the range and return an error if not:
The match can also be expressed with the
and_then
andmap_err
combinators: