use nom::error::{ErrorKind, ParseError}; use nom::{Err, IResult, Parser}; pub(crate) fn many0(mut f: F) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |mut i: I| { let mut acc = Vec::with_capacity(4); loop { match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, acc)), Err(e) => return Err(e), Ok((i1, o)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many0))); } i = i1; acc.push(o); } } } } } pub(crate) fn many1(mut f: F) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |mut i: I| match f.parse(i.clone()) { Err(Err::Error(err)) => Err(Err::Error(E::append(i, ErrorKind::Many1, err))), Err(e) => Err(e), Ok((i1, o)) => { let mut acc = Vec::with_capacity(4); acc.push(o); i = i1; loop { match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, acc)), Err(e) => return Err(e), Ok((i1, o)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))); } i = i1; acc.push(o); } } } } } } pub(crate) fn many_till( mut f: F, mut g: G, ) -> impl FnMut(I) -> IResult, P), E> where I: Clone + PartialEq, F: Parser, G: Parser, E: ParseError, { move |mut i: I| { let mut res = Vec::new(); loop { match g.parse(i.clone()) { Ok((i1, o)) => return Ok((i1, (res, o))), Err(Err::Error(_)) => { match f.parse(i.clone()) { Err(Err::Error(err)) => { return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))) } Err(e) => return Err(e), Ok((i1, o)) => { // loop trip must always consume (otherwise infinite loops) if i1 == i { return Err(Err::Error(E::from_error_kind( i1, ErrorKind::ManyTill, ))); } res.push(o); i = i1; } } } Err(e) => return Err(e), } } } }