1use crate::input::InputError;
2use crate::parser::Parser;
3use std::iter::FusedIterator;
4
5#[derive(Copy, Clone)]
9#[must_use = "iterators are lazy and do nothing unless consumed"]
10pub struct ParserIterator<'a, P> {
11 pub(super) input: &'a str,
12 pub(super) remaining: &'a [u8],
13 pub(super) parser: P,
14}
15
16impl<'a, P: Parser> Iterator for ParserIterator<'a, P> {
17 type Item = Result<P::Output<'a>, InputError>;
18
19 #[inline]
20 fn next(&mut self) -> Option<Self::Item> {
21 if self.remaining.is_empty() {
22 return None;
23 }
24
25 match self.parser.parse(self.remaining) {
26 Ok((v, remaining)) => {
27 self.remaining = remaining;
28 Some(Ok(v))
29 }
30 Err((err, remaining)) => {
31 self.remaining = &[]; Some(Err(InputError::new(self.input, remaining, err)))
33 }
34 }
35 }
36}
37
38impl<P: Parser> FusedIterator for ParserIterator<'_, P> {}
39
40#[derive(Copy, Clone)]
44#[must_use = "iterators are lazy and do nothing unless consumed"]
45pub struct ParserMatchesIterator<'a, P> {
46 pub(super) remaining: &'a [u8],
47 pub(super) parser: P,
48}
49
50impl<'a, P: Parser> Iterator for ParserMatchesIterator<'a, P> {
51 type Item = P::Output<'a>;
52
53 #[inline]
54 fn next(&mut self) -> Option<Self::Item> {
55 while !self.remaining.is_empty() {
56 if let Ok((v, remaining)) = self.parser.parse(self.remaining) {
57 self.remaining = remaining;
58 return Some(v);
59 }
60 self.remaining = &self.remaining[1..];
61 }
62 None
63 }
64}
65
66impl<P: Parser> FusedIterator for ParserMatchesIterator<'_, P> {}