# Glue
[](https://travis-ci.org/anarchistmae/glue-rs)
[](https://crates.io/crates/glue)
[](https://docs.rs/glue)

[](https://opensource.org/licenses/MIT)

Glue is a parser combinator framework that is designed for parsing text based formats, it is easy to use and relatively efficient.
## Usage
```rust
use glue::prelude::*;
match merge(one_or_more(is(alphabetic))).parse("foobar") {
Ok((result, _)) => {
println!("Found: {}", result);
},
Err(_) => {
println!("Nothing found!");
}
}
```
### Writing your own parser functions
```rust
use glue::prelude::*;
#[derive(Debug, PartialEq)]
enum Token {
Identifier(String),
}
fn identifier<I: Parsable>() -> impl Parser<I, Token> {
move |input: I| {
let (token, input) = merge(one_or_more(is(alphabetic))).parse(input)?;
Ok((Token::Identifier(token.to_string()), input))
}
}
assert_eq!(identifier().parse("foobar"), Ok((
Token::Identifier("foobar".into()),
""
)));
```
### Pretty human readable error messages
Glue does the hard work of implementing error messages for you, have a look at [this example] which created the following message:
```
1 │ foo xxx
· │ ┃
· ┢━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
· ┃ Unexpected 'xxx' ┃
· ┃ Expected bar ┃
· ┃ At 1:7 of path/to/file ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
```
For more detailed examples, look in the [examples directory] in the [git repository].
[git repository]: https://github.com/anarchistmae/glue-rs
[examples directory]: https://github.com/anarchistmae/glue-rs/tree/master/examples
[this example]: https://github.com/anarchistmae/glue-rs/blob/master/examples/printable_error.rs
### List of parsers and combinators
#### Branches
<dl>
<dt><code>all((Parser, ...))</code></dt>
<dd>Run each of the provided parsers and return the first that is successful.</dd>
<dt><code>either(Parser, Parser)</code></dt>
<dd>Run either parser returning whichever succeeds.</dd>
<dt><code>optional()</code></dt>
<dd>Run a parser and return its result on success or an empty result on failure.</dd>
</dl>
#### Matches
<dl>
<dt><code>empty()</code></dt>
<dd>Matches nothing and always succeeds, useful as a placeholder in tuples</dd>
<dt><code>is(Testable)</code></dt>
<dd>Match a character using a callback, string or anything that implements `Testable`.</dd>
<dt><code>isnt(Testable)</code></dt>
<dd>Match negatively, a character using a callback, string or anything that implements `Testable`.</dd>
<dt><code>literal(match: &str)</code></dt>
<dd>Match a literal string.</dd>
<dt><code>take(number: usize)</code></dt>
<dd>Match a specific number of characters.</dd>
</dl>
#### Repeaters
<dl>
<dt><code>min_to_max(minimum: usize, maximum: usize, Parser)</code></dt>
<dd>Run a parser a minimum number of times and up to a maximum.</dd>
<dt><code>min_or_more(minimum: usize, Parser)</code></dt>
<dd>Run a parser a minimum number or more times.</dd>
<dt><code>zero_to_max(maximum: usize, Parser)</code></dt>
<dd>Run a parser zero to a maximum number of times.</dd>
<dt><code>zero_or_more(Parser)</code></dt>
<dd>Run a parser zero or more times until it has matched everything it can.</dd>
<dt><code>one_to_max(maximum: usize, Parser)</code></dt>
<dd>Run a parser one to a maximum number of times.</dd>
<dt><code>one_or_more(Parser)</code></dt>
<dd>Run a parser one or more times until it has matched everything it can.</dd>
<dt><code>merge(Parser)</code></dt>
<dd>Run a parsers that return multiple results and turns them into a single result.</dd>
</dl>
#### Sequences
<dl>
<dt><code>both(Parser, Parser)</code></dt>
<dd>Run both parsers where one must follow the other.</dd>
<dt><code>all((Parser, ...))</code></dt>
<dd>Run each of the provided parsers and in the specified order and return all of the results.</dd>
</dl>
#### Structures
<dl>
<dt><code>separated_list(separator: Parser, Parser)</code></dt>
<dd>Run a parser many times, separated by another parser.</dd>
</dl>