yap 0.5.0

Yet Another Parser library. A lightweight, dependency free, parser combinator inspired set of utility methods to help with parsing strings and slices.
Documentation
# Yap: Yet another (rust) parsing library

[![API docs](https://docs.rs/yap/badge.svg)](https://docs.rs/yap)

This crate helps you to parse input strings and slices by building on the `Iterator` interface.

The aim of this crate is to provide transparent, flexible and easy to understand parsing utilities 
which work on arbitrary slices and strings. Some goals of this library are:

- Be simple but flexible. The entire interface is visible on the `Tokens` trait, and everything used
  internally to implement those functions can be used by you, too.
- Do the obvious thing where possible. For this library, that generally means using backtracking
  functions which won't consume any input unless they successfully parse it.
- Make it possible to return custom error and location information anywhere you might need it.
- Work with standard language features by offering an iterator based interface, rather than requiring
  specific combinators for control flow and such.

Have a look at the `Tokens` trait for all of the parsing methods, and examples for each.

Here's what it looks like:

```rust
use yap::{ 
    // This trait has all of the parsing methods on it:
    Tokens,
    // Allows you to use `.into_tokens()` on strings and slices, 
    // to get an instance of the above:
    IntoTokens
};

// Step 1: convert some tokens into something implementing `Tokens`
// ================================================================

let mut tokens = "1+2/3-4,foobar".into_tokens();

// Step 2: Parse some things from our tokens
// =========================================

#[derive(PartialEq,Debug)]
enum Op { Plus, Minus, Divide }
#[derive(PartialEq,Debug)]
enum OpOrDigit { Op(Op), Digit(u32) }

// The `Tokens` trait builds on `Iterator` and so looks similar,
// as well as having all of the normal `Iterator` methods on it.
fn parse_op(mut t: impl Tokens<Item=char>) -> Option<Op> {
    match t.next()? {
        '-' => Some(Op::Minus),
        '+' => Some(Op::Plus),
        '/' => Some(Op::Divide),
        _ => None
    }
}

fn parse_digit(mut tokens: impl Tokens<Item=char>) -> Option<u32> {
    let c = tokens.next()?;
    c.to_digit(10)
}

// Combinator functions exist which accept functions that consume tokens,
// and combine them. Here, we parse digits separated by operators, leaving
// any input that does not match this.
//
// These functions themselves tend to return iterators, so that you can 
// collect up the results however you choose. No input is consumed beyond 
// that which was successfully parsed.
let output: Vec<_> = tokens.sep_by_all(
    |t| parse_digit(t).map(OpOrDigit::Digit), 
    |t| parse_op(t).map(OpOrDigit::Op)
).collect();

// Step 3: do whatever you like with the rest of the input!
// ========================================================

// This is available on the concrete type that strings
// are converted into (rather than on the `Tokens` trait):
let remaining = tokens.remaining();

assert_eq!(remaining, ",foobar");
```