Implement Iterator for Parser and Scanner

This commit is contained in:
Simon Ask Ulsnes 2024-02-04 11:46:38 +01:00
parent a171e0013a
commit fec143f0c0
3 changed files with 33 additions and 12 deletions

View file

@ -259,8 +259,7 @@ impl Document {
/// end has been reached.
///
/// An application must not alternate the calls of [`Document::load()`] with
/// the calls of [`yaml_parser_scan()`](crate::yaml_parser_scan) or
/// [`Parser::parse()`]. Doing this will break the parser.
/// the calls of [`Parser::parse()`]. Doing this will break the parser.
pub fn load(parser: &mut Parser) -> Result<Document, ComposerError> {
let mut document = Document::new(None, &[], false, false);
document.nodes.reserve(16);

View file

@ -164,6 +164,20 @@ fn SKIP_TOKEN(parser: &mut Parser) {
);
}
impl<'r> Iterator for Parser<'r> {
type Item = Result<Event, ParserError>;
fn next(&mut self) -> Option<Self::Item> {
if self.scanner.stream_end_produced || self.state == ParserState::End {
None
} else {
Some(self.parse())
}
}
}
impl<'r> core::iter::FusedIterator for Parser<'r> {}
impl<'r> Parser<'r> {
/// Create a parser.
pub fn new() -> Parser<'r> {
@ -206,9 +220,8 @@ impl<'r> Parser<'r> {
/// [`EventData::StreamEnd`](crate::EventData::StreamEnd).
///
/// An application must not alternate the calls of [`Parser::parse()`] with
/// the calls of [`yaml_parser_scan()`](crate::yaml_parser_scan) or
/// [`Document::load()`](crate::Document::load). Doing this will break the
/// parser.
/// the calls of [`Document::load()`](crate::Document::load). Doing this
/// will break the parser.
pub fn parse(&mut self) -> Result<Event, ParserError> {
if self.scanner.stream_end_produced || self.state == ParserState::End {
return Ok(Event {

View file

@ -180,18 +180,27 @@ fn READ_LINE_STRING(scanner: &mut Scanner, string: &mut String) {
}
}
impl<'r> Iterator for Scanner<'r> {
type Item = Result<Token, ScannerError>;
fn next(&mut self) -> Option<Self::Item> {
if self.stream_end_produced {
None
} else {
Some(self.scan())
}
}
}
impl<'r> core::iter::FusedIterator for Scanner<'r> {}
impl<'r> Scanner<'r> {
/// Scan the input stream and produce the next token.
///
/// Call the function subsequently to produce a sequence of tokens corresponding
/// to the input stream. The initial token has the type
/// Call the function subsequently to produce a sequence of tokens
/// corresponding to the input stream. The initial token has the type
/// [`TokenData::StreamStart`] while the ending token has the type
/// [`TokenData::StreamEnd`].
///
/// An application must not alternate the calls of
/// [`yaml_parser_scan()`](crate::yaml_parser_scan) with the calls of
/// [`Parser::parse()`] or [`Document::load()`](crate::Document::load). Doing
/// this will break the parser.
pub fn scan(&mut self) -> Result<Token, ScannerError> {
if self.stream_end_produced {
return Ok(Token {