diff --git a/src/combinator/mod.rs b/src/combinator/mod.rs index fe6655b98..df847f5e8 100644 --- a/src/combinator/mod.rs +++ b/src/combinator/mod.rs @@ -869,8 +869,8 @@ where /// Creates an iterator from input data and a parser. /// -/// Call the iterator's [ParserIterator::finish] method to get the remaining input if successful, -/// or the error value if we encountered an error. +/// Call the iterator's [ParserIterator::finish] method to get the remaining +/// input if successful, or the error value if we encountered an error. /// /// On [`Err::Error`], iteration will stop. To instead chain an error up, see [`cut`]. /// @@ -887,7 +887,7 @@ where /// assert_eq!(parsed, [("abc", 3usize), ("defg", 4), ("hijkl", 5), ("mnopqr", 6)].iter().cloned().collect()); /// assert_eq!(res, Ok(("123", ()))); /// ``` -pub fn iterator(input: Input, f: F) -> ParserIterator +pub fn iterator(input: Input, f: F) -> ParserIterator where F: Parser, Error: ParseError, @@ -895,21 +895,40 @@ where ParserIterator { iterator: f, input, - state: Some(State::Running), + state: State::Running, + _streaming: PhantomData, + } +} + +/// Same as [iterator] but for complete parsers +pub fn iterator_complete( + input: Input, + f: F, +) -> ParserIterator +where + F: Parser, + Error: ParseError, +{ + ParserIterator { + iterator: f, + input, + state: State::Running, + _streaming: PhantomData, } } /// Main structure associated to the [iterator] function. -pub struct ParserIterator { +pub struct ParserIterator { iterator: F, input: I, - state: Option>, + state: State, + _streaming: std::marker::PhantomData, } -impl ParserIterator { +impl ParserIterator { /// Returns the remaining input if parsing was successful, or the error if we encountered an error. - pub fn finish(mut self) -> IResult { - match self.state.take().unwrap() { + pub fn finish(self) -> IResult { + match self.state { State::Running | State::Done => Ok((self.input, ())), State::Failure(e) => Err(Err::Failure(e)), State::Incomplete(i) => Err(Err::Incomplete(i)), @@ -917,33 +936,33 @@ impl ParserIterator { } } -impl core::iter::Iterator for ParserIterator +impl core::iter::Iterator for ParserIterator where F: Parser, Input: Clone, + S: IsStreaming, { type Item = Output; fn next(&mut self) -> Option { - if let State::Running = self.state.take().unwrap() { + if let State::Running = self.state { let input = self.input.clone(); - match (self.iterator).parse(input) { + match (self.iterator).process::>(input) { Ok((i, o)) => { self.input = i; - self.state = Some(State::Running); Some(o) } Err(Err::Error(_)) => { - self.state = Some(State::Done); + self.state = State::Done; None } Err(Err::Failure(e)) => { - self.state = Some(State::Failure(e)); + self.state = State::Failure(e); None } Err(Err::Incomplete(i)) => { - self.state = Some(State::Incomplete(i)); + self.state = State::Incomplete(i); None } }