1use nom::{2 branch::alt,3 bytes::complete::tag,4 character::complete::{char, line_ending, one_of},5 combinator::{map_res, recognize},6 error::{FromExternalError, ParseError},7 multi::{many0, many1},8 sequence::delimited,9 IResult,10};1112// Bind the given parser to the given value (map_res short).13pub fn bind<'a, F: 'a, T: Copy, O, E: ParseError<&'a str> + FromExternalError<&'a str, ()>>(14 inner: F,15 val: T,16) -> impl FnMut(&'a str) -> IResult<&'a str, T, E>17where18 F: FnMut(&'a str) -> IResult<&'a str, O, E>,19{20 map_res(inner, move |_| -> Result<T, ()> { Ok(val) })21}2223// Parse on of the given strings and return the given value.24pub fn str<'a, T: Copy, E: ParseError<&'a str> + FromExternalError<&'a str, ()> + 'a>(25 name: &'a str,26 other: &'a str,27 val: T,28) -> impl FnMut(&'a str) -> IResult<&'a str, T, E> {29 bind(alt((tag(name), tag(other))), val)30}3132pub fn digits(input: &str) -> IResult<&str, u32> {33 map_res(recognize(many1(one_of("0123456789"))), |input: &str| {34 u32::from_str_radix(input, 10)35 })(input)36}3738pub fn ws<'a, F: 'a, O, E: ParseError<&'a str>>(39 inner: F,40) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>41where42 F: Fn(&'a str) -> IResult<&'a str, O, E>,43{44 delimited(many0(char(' ')), inner, many0(char(' ')))45}4647pub fn empty_lines<'a, F: 'a, O, E: ParseError<&'a str> + 'a>(48 inner: F,49) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>50where51 F: Fn(&'a str) -> IResult<&'a str, O, E>,52{53 delimited(many0(ws(line_ending)), inner, many0(ws(line_ending)))54}