pub trait Parser<In, Out> {
    // Required method
    fn try_parse(&self, input: Input<In>) -> Res<In, Out>;

    // Provided methods
    fn map<F, Mapped>(self, f: F) -> Map<Self, F, Out>
       where Self: Sized,
             F: Fn(Out) -> Mapped { ... }
    fn or<P>(self, next: P) -> Or<Self, P>
       where Self: Sized { ... }
    fn when<F>(self, pred: F) -> Predicate<Self, F>
       where Self: Sized,
             F: Fn(Out) -> bool { ... }
    fn repeated<R: RepetitionArgument>(self, count: R) -> Repeat<Self, R>
       where Self: Sized { ... }
    fn optional(self) -> Optional<Self>
       where Self: Sized { ... }
    fn peeked(self) -> Peeked<Self>
       where Self: Sized { ... }
    fn not_peeked(self) -> NotPeeked<Self, Out>
       where Self: Sized { ... }
    fn and_then<F, U, E>(self, f: F) -> AndThen<Self, F, Out>
       where Self: Sized,
             F: Fn(Out) -> Result<U, E>,
             E: Error { ... }
    fn label(self, l: &'static str) -> Label<Self>
       where Self: Sized { ... }
    fn err<E, F>(self, f: F) -> UserErr<Self, F, E>
       where Self: Sized,
             F: Fn() -> E,
             for<'a> E: Error + 'a { ... }
}
Expand description

A trait for parsers

A parser takes in input and either outputs a value or reports an error.

The Parser trait is already implemented slices and &strs.

Required Methods§

source

fn try_parse(&self, input: Input<In>) -> Res<In, Out>

Recognizes a value from the input and returns the result

Reports an error if the input could not be matched.

Provided Methods§

source

fn map<F, Mapped>(self, f: F) -> Map<Self, F, Out>where Self: Sized, F: Fn(Out) -> Mapped,

Returns a parser that maps a Parser<In, Out> to Parser<In, Mapped> by applying a function to the result of the parser if it succeeded.

use parser_compose::Parser;

let msg = "a";

let (value, _) = "a".map(|s| s.to_ascii_uppercase()).try_parse(msg.into()).unwrap();

assert_eq!(value, "A");
source

fn or<P>(self, next: P) -> Or<Self, P>where Self: Sized,

Returns a parser that succeeds if self does. Otherwise, it’s outcome is that of next.

use  parser_compose::Parser;

let msg = "a";

let (value, _) = "1".or("a").try_parse(msg.into()).unwrap();

assert_eq!(value, "a");
source

fn when<F>(self, pred: F) -> Predicate<Self, F>where Self: Sized, F: Fn(Out) -> bool,

Returns a new parser that succeeds if the predicate returns true. The predicate is given the extracted value of the current parser as an argument

use parser_compose::{any_str,Parser};

let msg = "boo";

let (value, _) = any_str.when(|s| s == "b").try_parse(msg.into()).unwrap();

assert_eq!(value, "b");
source

fn repeated<R: RepetitionArgument>(self, count: R) -> Repeat<Self, R>where Self: Sized,

Returns a parser that suceeds if it is able to repeat count times.

count can be:

  • A single usize (e.g. 8): The parser will try to match at least 8 times and return a Vec of length 8 if it succeeds
use parser_compose::Parser;

let msg = "AAAA";

let (value, rest) = "A".repeated(3).try_parse(msg.into()).unwrap();

assert_eq!(value, vec!["A", "A", "A"]);
assert_eq!(rest, "A");
  • A range bounded inclusively from below (e.g. 3..): The parser will try to match at least 3 times, but possibly more. If it succeeds, the returned Vec is be guaranteed to have a value greater than 3.
use parser_compose::Parser;

let msg = "AAAA";
let (value, rest) = "A".repeated(2..).try_parse(msg.into()).unwrap();

assert_eq!(value, vec!["A", "A", "A", "A"]);
assert_eq!(rest, "");
  • A range bounded inclusively from above (e.g. ..=4): The parser will try to match at most 4 times, but possibly less (including zero times!). If it succeeds, the returned Vec will have at most 4 elements
use parser_compose::Parser;

let msg = "AA";
let (value, rest) = "A".repeated(..=4).try_parse(msg.into()).unwrap();

assert_eq!(value, vec!["A", "A"]);
assert_eq!(rest, "");
  • A range bounded inclusively from above and below (e.g. 3..=5): The parser will try to match at least 3 times and at most 5 times. If it succeeds, the returned Vec will have a length between 3 and 5
use parser_compose::Parser;

let msg = "AAAA";
let (value, rest) = "A".repeated(2..=3).try_parse(msg.into()).unwrap();

assert_eq!(value, vec!["A", "A", "A"]);
assert_eq!(rest, "A");
source

fn optional(self) -> Optional<Self>where Self: Sized,

Returns a parser always succeeds but wraps the output in an Option<Out>. If the original parser would have failed, the parser outputs a None.

use parser_compose::Parser;

let msg = "a";

let ((b, a), _) = ("b".optional(), "a").try_parse(msg.into()).unwrap();

assert_eq!(b, None);
assert_eq!(a, "a");
source

fn peeked(self) -> Peeked<Self>where Self: Sized,

Returns a parser that succeeds or fails as normal, but never consumes any input regardless of the outcome. This can be used to look ahead.

use parser_compose::Parser;

// Recognize the sequence "a" followed by "b", but only if it is followed by a "c"
let a_then_b = ("a", "b", "c".peeked());

let (value, rest) = a_then_b.try_parse("abc".into()).unwrap();
// note: the value gets recognized and returned, but it does not consume it.
assert_eq!(value, ("a".to_string(), "b".to_string(), "c".to_string()));
assert_eq!(rest, "c");

let result = a_then_b.try_parse("abb".into());
assert!(result.is_err());
source

fn not_peeked(self) -> NotPeeked<Self, Out>where Self: Sized,

Reverse of peeked(). Returns a parse that succeeds if it was not able to recognize the input and fails if it was able to. It never consumes any input.

use parser_compose::Parser;

// This parser matches "foo", but only if it is not followed by  "bar"
let parser = ("foo", "bar".not_peeked());

let msg = "foobar";

let result = parser.try_parse(msg.into());

assert!(result.is_err());

let (value, rest) = parser.try_parse("foobaz".into()).unwrap();

assert_eq!(value, (String::from("foo"), ()));
assert_eq!(rest, "baz");
source

fn and_then<F, U, E>(self, f: F) -> AndThen<Self, F, Out>where Self: Sized, F: Fn(Out) -> Result<U, E>, E: Error,

Returns a parser that is similar to map() in its behavior, except that the provided closure may fail. The parser reports whatevere error the closure fails with.

use parser_compose::{Parser};

let msg = [98].as_slice();

let (value, _) = [98].and_then(|b| {
    // converting to utf8 can fail
    String::from_utf8(b)
}).try_parse(msg.into()).unwrap();

assert_eq!("b", value);
source

fn label(self, l: &'static str) -> Label<Self>where Self: Sized,

Returns an identical parser, but with a label. Labels are used when reporting errors. See ErrorTree for more information.

source

fn err<E, F>(self, f: F) -> UserErr<Self, F, E>where Self: Sized, F: Fn() -> E, for<'a> E: Error + 'a,

Returns an identical parser that will report the given error when it fails. See ErrorTree for more information on abount error handling

Implementations on Foreign Types§

source§

impl<'input, 'pat> Parser<&'input str, String> for &'pat str

The Parser trait is implemented for string slices, which means all &strs will have the try_parse() method. Calling it will try to do a prefix match of the input with the &str used as the pattern.

use parser_compose::Parser;

let msg = "HELLO";

let (res, rest) = "HE".try_parse(msg.into()).unwrap();

assert_eq!(res, "HE");
assert_eq!(rest, "LLO");
source§

fn try_parse(&self, input: Input<&'input str>) -> Res<&'input str, String>

source§

impl<'pat, 'input, T> Parser<&'input [T], Vec<T>> for &'pat [T]where T: PartialEq + Clone + Debug,

The Parser trait is implemented for all slices, which means all &[T] will have the try_parse() method. Calling it will try to do a prefix match of the input with the slice used as the pattern.

use parser_compose::Parser;

let msg = &['H', 'E', 'L', 'L', 'O'][..];

let (res, rest) = ['H', 'E'].as_slice().try_parse(msg.into()).unwrap();


assert_eq!(res, &['H', 'E'][..]);
assert_eq!(rest, &['L', 'L', 'O'][..]);
source§

fn try_parse(&self, input: Input<&'input [T]>) -> Res<&'input [T], Vec<T>>

source§

impl<In, P0, O0> Parser<In, (O0,)> for (P0,)where P0: Parser<In, O0>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0,)>

source§

impl<In, P0, O0, P1, O1> Parser<In, (O0, O1)> for (P0, P1)where P0: Parser<In, O0>, P1: Parser<In, O1>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0, O1)>

source§

impl<In, P0, O0, P1, O1, P2, O2> Parser<In, (O0, O1, O2)> for (P0, P1, P2)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0, O1, O2)>

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3> Parser<In, (O0, O1, O2, O3)> for (P0, P1, P2, P3)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0, O1, O2, O3)>

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4> Parser<In, (O0, O1, O2, O3, O4)> for (P0, P1, P2, P3, P4)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0, O1, O2, O3, O4)>

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5> Parser<In, (O0, O1, O2, O3, O4, O5)> for (P0, P1, P2, P3, P4, P5)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

fn try_parse(&self, input: Input<In>) -> Res<In, (O0, O1, O2, O3, O4, O5)>

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6> Parser<In, (O0, O1, O2, O3, O4, O5, O6)> for (P0, P1, P2, P3, P4, P5, P6)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7)> for (P0, P1, P2, P3, P4, P5, P6, P7)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>, P10: Parser<In, O10>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6, P7, O7, P8, O8, P9, O9, P10, O10, P11, O11> Parser<In, (O0, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11)> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)where P0: Parser<In, O0>, P1: Parser<In, O1>, P2: Parser<In, O2>, P3: Parser<In, O3>, P4: Parser<In, O4>, P5: Parser<In, O5>, P6: Parser<In, O6>, P7: Parser<In, O7>, P8: Parser<In, O8>, P9: Parser<In, O9>, P10: Parser<In, O10>, P11: Parser<In, O11>,

A tuple of parsers is treated as a parser that tries its inner parsers in turn, feeding the leftover input from the first as the input to the other and so on

Calling the .try_parse() on the tuple returns a new tuple containing the extracted values.

This is implemented for tuples up to 12 items long

Implementors§

source§

impl<'input> Parser<&'input str, String> for AsciiStr

source§

impl<'input> Parser<&'input [u8], Vec<u8>> for Byte

source§

impl<In, Out, E, P, F, U> Parser<In, U> for AndThen<P, F, Out>where P: Parser<In, Out>, F: Fn(Out) -> Result<U, E>, for<'a> E: Error + 'a,

source§

impl<In, Out, F> Parser<In, Out> for Fwhere F: Fn(Input<In>) -> Res<In, Out>,

The Parser trait is automatically implemented for any function with the following signature:

Fn(Input<In>) -> parser_compose::Res<In, Out>

See the trait documentation for more info about the type parameters.

source§

impl<In, Out, P1, P2> Parser<In, Out> for Or<P1, P2>where P1: Parser<In, Out>, P2: Parser<In, Out>, In: Clone,

source§

impl<In, Out, P> Parser<In, Option<Out>> for Optional<P>where In: Clone, P: Parser<In, Out>,

source§

impl<In, Out, P> Parser<In, Out> for Peeked<P>where In: Clone, P: Parser<In, Out>,

source§

impl<In, Out, P, F> Parser<In, Out> for Predicate<P, F>where P: Parser<In, Out>, F: Fn(Out) -> bool, Out: Clone,

source§

impl<In, Out, P, F, M> Parser<In, M> for Map<P, F, Out>where P: Parser<In, Out>, F: Fn(Out) -> M,

source§

impl<In, Out, P, R> Parser<In, Vec<Out>> for Repeat<P, R>where P: Parser<In, Out>, R: RepetitionArgument, In: Clone,