// Write two separate parser functions // One function returns `impl Parser<>` // The other function returns `FnMut(I) -> IResult>( mut parser: impl Parser<&'a str, i32, E>, ) -> impl FnMut(&'a str) -> IResult<&'a str, Container, E> { move |input| { let (input, value) = parser.parse(input)?; Ok((input, Container(value))) } } /* // This form doesn't work. It is not possible in this case to get the ownership // declarations correct on parser. The reason I would want to do this is for more // concise representation of parse_container_a. It probably fails because map consumes // the parser. fn parse_container_b<'a, E: ParseError<&'a str>, P>( mut parser: P, ) -> impl Parser<&'a str, Container, E> where P: Parser<&'a str, i32, E>, { move |input| parser.map(|val| Container(val)).parse(input) } */ #[allow(dead_code)] fn parse_container_c<'a, E: ParseError<&'a str>>( parser: impl Parser<&'a str, i32, E>, ) -> impl Parser<&'a str, Container, E> { parser.map(Container) } /* // This form also doesn't work, for the same reason as parse_container_b doesn't work. fn parse_container_d<'a, E: ParseError<&'a str>>( parser: impl Parser<&'a str, i32, E>, ) -> impl FnMut(&'a str) -> IResult<&'a str, Container, E> { |input| parser.map(|val| Container(val)).parse(input) } */ // If I really want to do forms b and d, this works. I do the parser combination before // creating the resulting function. #[allow(dead_code)] fn parse_container_e<'a, E: ParseError<&'a str>>( parser: impl Parser<&'a str, i32, E>, ) -> impl Parser<&'a str, Container, E> { let mut parser = parser.map(Container); move |input| parser.parse(input) } #[allow(dead_code)] fn parse_number_a<'a, E: ParseError<&'a str>>() -> impl FnMut(&'a str) -> IResult<&'a str, i32, E> { parse_number } #[allow(dead_code)] fn parse_number_b<'a, E: ParseError<&'a str>>() -> impl Parser<&'a str, i32, E> { parse_number } #[allow(dead_code)] fn parse_number<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, i32, E> { let (input, val) = digit1(input)?; Ok((input, val.parse::().unwrap())) } #[cfg(test)] mod tests { use super::*; use cool_asserts::assert_matches; const DATA: &'static str = "15"; #[test] fn function() { let resp = parse_number_a::>() .map(|val| Container(val)) .parse(DATA); assert_matches!(resp, Ok((_, content)) => assert_eq!(content, Container(15)) ); } #[test] fn parser() { let resp = parse_number_b::>() .map(|val| Container(val)) .parse(DATA); assert_matches!(resp, Ok((_, content)) => assert_eq!(content, Container(15)) ); } #[test] fn parser_composition_a() { let resp = parse_container_a::>(parse_number_a()).parse(DATA); assert_matches!(resp, Ok((_, content)) => assert_eq!(content, Container(15)) ); } #[test] fn parser_composition_c() { let resp = parse_container_c::>(parse_number_b()).parse(DATA); assert_matches!(resp, Ok((_, content)) => assert_eq!(content, Container(15)) ); } }