use nom::{ branch::alt, bytes::complete::tag, character::complete::{line_ending, space0, space1, u32}, combinator::{eof, opt, value}, error::ParseError, multi::many0, sequence::{delimited, preceded, terminated, tuple}, Err, IResult, Parser, }; pub fn extract_result>( mut parser: F, ) -> impl FnMut(I) -> Result> where F: FnMut(I) -> IResult, { move |input: I| parser(input).map(|(_, value)| value) } pub fn ignore>(mut parser: F) -> impl FnMut(I) -> Result> where F: FnMut(I) -> IResult, { move |input: I| parser(input).map(|(i, _)| i) } pub fn eol_terminated<'a, F, O, E: ParseError<&'a str>>( line: F, ) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> where F: Parser<&'a str, O, E>, { terminated(line, alt((line_ending, eof))) } pub fn usize<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, usize, E> { u32.map(|v| v as usize).parse(input) } pub fn true_false<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, bool, E> { alt((value(true, tag("true")), value(false, tag("false"))))(input) } pub fn empty_lines<'a, E: ParseError<&'a str>>(input: &'a str) -> Result<&'a str, Err> { ignore(tuple((many0(line_ending), opt(eof))))(input) } pub fn trim_left1<'a, F, O, E: ParseError<&'a str>>( inner: F, ) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> where F: Parser<&'a str, O, E>, { preceded(space1, inner) } pub fn trim0<'a, F, O, E: ParseError<&'a str>>( inner: F, ) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> where F: Parser<&'a str, O, E>, { delimited(space0, inner, space0) } pub fn trim1<'a, F, O, E: ParseError<&'a str>>( inner: F, ) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> where F: Parser<&'a str, O, E>, { delimited(space1, inner, space1) }