lib/event: add module documentation

This commit is contained in:
Paul Stemmet 2021-12-29 14:15:12 +00:00 committed by Paul Stemmet
parent fcfb870583
commit 056b9e27be
1 changed files with 91 additions and 0 deletions

View File

@ -4,6 +4,97 @@
* was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
//! This module exposes the [Parser] struct and related
//! types. The Parser takes a sequence of [Token]s produced
//! by a generic [Read] interface, and converts them
//! into a series of [Event]s. These events are the core of
//! higher level functionality exposed by this library.
//!
//! They (and the Parser) are also the lowest level public
//! API, as [Read] is a sealed trait. Typically, you
//! shouldn't need to interact with anything in this module
//! directly, but if you want to build specialized code
//! which directly consumes an event stream, e.g to avoid
//! paying for node collation / storage, scalar type
//! resolution, etc.
//!
//! If you are going to use this module, you should read
//! the following to get an understanding of how [Read]
//! impls, the [Parser], and [Event]s work together.
//!
//! ## Invoking the Parser
//!
//! Each [Parser] must be passed a [PeekReader<'de, T>]
//! where `T: Read`. PeekReader has a blanket [From]
//! impl for any type implementing [Read]. Once passed to a
//! [Parser], _it is a logic error to pass that PeekReader
//! to a different [Parser]_. The outcome is not specified,
//! but will likely either be garbage or and error.
//!
//! The two interesting methods on a [Parser] are:
//!
//! 1. [next_event](Parser.next_event)
//! 2. [into_iter](Parser.into_iter)
//!
//! Both take one argument, the [PeekReader] associated
//! with this [Parser]. The first, `next_event` returns
//! the next [Event] (naturally), while the second,
//! `into_iter`, returns an interface that implements
//! [Iterator], allowing one to hook into that entire
//! ecosystem.
//!
//! ## Understanding Events
//!
//! Each event produced represents an important semantic
//! change in the underlying YAML byte stream. Broadly,
//! these can be categorized into three spaces:
//!
//! 1. Virtual / Marker
//! - [StreamStart](Event::StreamStart),
//! - [StreamEnd](Event::StreamEnd),
//! - [DocumentStart](Event::DocumentStart),
//! - [DocumentEnd](Event::DocumentEnd),
//!
//! 2. Nesting change (+-)
//! - [MappingStart](Event::MappingStart),
//! - [MappingEnd](Event::MappingEnd),
//! - [SequenceStart](Event::SequenceStart),
//! - [SequenceEnd](Event::SequenceEnd),
//!
//! 3. Data / Alias
//! - [Scalar](Event::Scalar),
//! - [Alias](Event::Alias),
//!
//! Together, these are used to produce the following
//! productions:
//!
//! ```text
//! stream := StreamStart document+ StreamEnd
//! document := DocumentStart content? DocumentEnd
//! content := Scalar | collection
//! collection := sequence | mapping
//! sequence := SequenceStart node* SequenceEnd
//! mapping := MappingStart (node node)* MappingEnd
//! node := Alias | content
//!
//! ? => 0 or 1 of prefix
//! * => 0 or more of prefix
//! + => 1 or more of prefix
//! () => production grouping
//! | => production logical OR
//! ```
//!
//! In addition to the various [Event] types, every [Node]
//! also provides a hint as to its placement in the stream
//! via its [NodeKind]. Together, these should allow users
//! to maintain relatively little external state regarding
//! the [Event] stream, beyond anything they wish to
//! collect from the stream.
//!
//! [Token]: enum@crate::token::Token
//! [Read]: trait@crate::reader::Read
//! [Node]: struct@crate::event::types::Node
use std::array::IntoIter as ArrayIter;
use crate::{