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<'a>> Iterator for ParserIterator<'a, P> {
17 type Item = Result<P::Output, 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<'a, P: Parser<'a>> FusedIterator for ParserIterator<'a, P> {}
39
40impl<'a, P: Parser<'a>> ParserIterator<'a, P> {
41 #[inline]
55 pub fn remaining(&self) -> &'a [u8] {
56 self.remaining
57 }
58}
59
60#[derive(Copy, Clone)]
64#[must_use = "iterators are lazy and do nothing unless consumed"]
65pub struct ParserMatchesIterator<'a, P> {
66 pub(super) remaining: &'a [u8],
67 pub(super) parser: P,
68}
69
70impl<'a, P: Parser<'a>> Iterator for ParserMatchesIterator<'a, P> {
71 type Item = P::Output;
72
73 #[inline]
74 fn next(&mut self) -> Option<Self::Item> {
75 while !self.remaining.is_empty() {
76 if let Ok((v, remaining)) = self.parser.parse(self.remaining) {
77 self.remaining = remaining;
78 return Some(v);
79 }
80 self.remaining = &self.remaining[1..];
81 }
82 None
83 }
84}
85
86impl<'a, P: Parser<'a>> FusedIterator for ParserMatchesIterator<'a, P> {}
87
88impl<'a, P: Parser<'a>> ParserMatchesIterator<'a, P> {
89 #[inline]
102 pub fn remaining(&self) -> &'a [u8] {
103 self.remaining
104 }
105}