Using the nom crate, I'm trying to write a parser that can recognize signed i32
number from a String
, i.e. can transform the string -42
into the i32
representation.
So far I've come up with the following, but I'm failing to parse negative numbers:
use nom::types::CompleteStr;
use std::str::FromStr;
named!(
i32_parser<CompleteStr, i32>,
map_res!(nom::digit, |CompleteStr(s)| i32::from_str(s))
);
#[test]
fn parse_i32_positive() {
assert_eq!(
i32_parser(CompleteStr::from("42")),
Ok((CompleteStr::from(""), 42))
);
}
#[test]
fn parse_i32_negative() {
assert_eq!(
i32_parser(CompleteStr::from("-42")),
Ok((CompleteStr::from(""), -42))
);
}
I've also tried the following, but with a cryptic compilation error:
named!(
i32_parser<CompleteStr, i32>,
map_res!(alt!(char!('-') | nom::digit), |CompleteStr(s)| i32::from_str(s))
);
^ expected char, found struct `nom::types::CompleteStr`
Any suggestion on how to fix it? Or a simpler way to achieve that with nom?
I'm explicitly looking to implement this with nom because I'm trying to parse a more complex structure. i32::from_str(s)
works for simple strings but it's not what I'm looking for.
The recognize!
macro can help you. It returns the parsed input string instead of the parser output, which can then be converted as usual. For example:
named!(i32_parser<&str, i32>,
map_res!(
recognize!(tuple!(opt!(char!('-')), digit)),
FromStr::from_str)
);