streamparser — incrementally parse input from a stream

crates.io version docs.rs version

This crate provides adapters to turn a stream of input into a sequence of parsed items, using a simple incremental parsing function. It supports both sync and async input and allows returning items that hold a reference to the input.

Usage

Add the crate to your Cargo.toml:

toml [dependencies] streamparser = "0.1"

Example

A complete example parsing whitespace-separated words from a stream:

```rust use std::{convert::Infallible, error::Error, io::Cursor}; use streamparser::{read::ReadSource, utf8::Utf8Adapter, Parse, Parsed, StreamParser, Streaming};

struct SplitWords;

impl<'a> Parse<'a> for SplitWords { type Input = &'a str; type Output = &'a str; type Error = Infallible;

fn parse(
    &mut self,
    input: Self::Input,
) -> Result<Streaming<Parsed<Self::Output>>, Self::Error> {
    let trimmed = input.trim_start();
    let trimmed_count = input.len() - trimmed.len();
    match trimmed.find(' ') {
        Some(end) => Ok(Streaming::Item((
            Some(&trimmed[..end]),
            trimmed_count + end,
        ))),
        None => Ok(Streaming::Incomplete),
    }
}

fn parse_eof(
    &mut self,
    input: Self::Input,
) -> Result<Parsed<Self::Output>, Self::Error> {
    let trimmed = input.trim();
    if !trimmed.is_empty() {
        Ok((Some(trimmed), input.len()))
    } else {
        Ok((None, input.len()))
    }
}

}

fn main() -> Result<(), Box> { let mut results = Vec::new(); let mut parser = StreamParser::new( Utf8Adapter::new(SplitWords), ReadSource::new(Cursor::new(b"words separated by whitespace"), 6), ); while let Some(streaming) = parser.get()? { match streaming { Streaming::Item(item) => { results.push(item.toowned()); } Streaming::Incomplete => parser.advance()?, } } asserteq!(results, vec!["words", "separated", "by", "whitespace",]); Ok(()) } ```

Documentation

Reference documentation

Developing

Releases