Skip to main content

oni_comb_parser/primitive/
take_while1.rs

1use core::marker::PhantomData;
2
3use crate::error::{ExpectError, Expected};
4use crate::fail::{Fail, PResult};
5use crate::input::Input;
6use crate::parser::Parser;
7
8pub struct TakeWhile1<F, I: Input>(F, PhantomData<fn(&mut I)>);
9
10pub fn take_while1<I: Input, F: FnMut(I::Token) -> bool>(f: F) -> TakeWhile1<F, I> {
11  TakeWhile1(f, PhantomData)
12}
13
14impl<I: Input, F> Parser<I> for TakeWhile1<F, I>
15where
16  F: FnMut(I::Token) -> bool,
17{
18  type Error = I::Error;
19  type Output = I::Slice;
20
21  #[inline]
22  fn parse_next(&mut self, input: &mut I) -> PResult<I::Slice, I::Error> {
23    let pos = input.offset();
24    let cp = input.checkpoint();
25    loop {
26      let item_cp = input.checkpoint();
27      match input.next_token() {
28        Some(t) if (self.0)(t) => {}
29        Some(_) => {
30          input.reset(item_cp);
31          break;
32        }
33        None => break,
34      }
35    }
36    if input.checkpoint() == cp {
37      return Err(Fail::Backtrack(I::Error::from_expected(
38        pos,
39        Expected::Description("at least one matching token"),
40      )));
41    }
42    Ok(input.slice_since(cp))
43  }
44}