pub trait Parser<In> {
    type Out;

    // Required method
    fn try_parse(&self, input: In) -> Option<(Self::Out, In)>;

    // Provided methods
    fn map<F, Mapped>(self, f: F) -> Map<Self, F>
       where Self: Sized,
             F: Fn(Self::Out) -> Mapped { ... }
    fn or<P>(self, next: P) -> Or<Self, P>
       where Self: Sized { ... }
    fn when<F>(self, predicate: F) -> Predicate<Self, F>
       where Self: Sized,
             F: Fn(Self::Out) -> bool { ... }
    fn fold<R, Op, Init, IV>(
        self,
        count: R,
        op: Op,
        init: Init
    ) -> Fold<Self, Op, Init>
       where R: RepetitionArgument,
             Init: Fn() -> IV,
             Op: Fn(IV, Self::Out) -> IV,
             Self: Sized { ... }
    fn repeats<R>(
        self,
        count: R
    ) -> Fold<Self, RepeatsOperation<Self::Out>, RepeatsInit>
       where Self: Sized,
             R: RepetitionArgument { ... }
    fn accumulate<R>(
        self,
        count: R
    ) -> Fold<Self, AccumulateOperation<Self::Out>, AccumulateInit<Self::Out>>
       where R: RepetitionArgument,
             Self: Sized { ... }
    fn input(self) -> Input<Self>
       where Self: Sized { ... }
    fn optional(self) -> Optional<Self>
       where Self: Sized { ... }
    fn peek(self) -> Peek<Self>
       where Self: Sized { ... }
    fn not(self) -> Not<Self>
       where Self: Sized { ... }
    fn and_then<F, U, E>(self, f: F) -> AndThen<Self, F>
       where Self: Sized,
             F: Fn(Self::Out) -> Result<U, E> { ... }
}
Expand description

A trait for parsers

A Parser accepts input of type In and tries to match it. If it succeeds, it returns a value of type Some<(Out, In)>. The first element of the tuple is the parser’s output, and the second is whatever is left of the input after parsing. If the parser fails, it returns None

Given a thing that implements Parser, calling one of the associated methods returns a new Parser that augments its functionality.

Required Associated Types§

source

type Out

The type this parser outputs if successfull

Required Methods§

source

fn try_parse(&self, input: In) -> Option<(Self::Out, In)>

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>
where Self: Sized, F: Fn(Self::Out) -> Mapped,

Returns a parser that applies the function f to its output

use parser_compose::Parser;

let msg = "a";

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

assert_eq!(value, "A");
source

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

Returns a parser that calls the next parser if it fails to match its input.

use  parser_compose::Parser;

let msg = "a";

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

assert_eq!(value, "a");
source

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

Returns a parser that only succeeds if pred returns true when given the parser’s output

use parser_compose::{first_utf8_scalar,Parser};

let msg = "boo";

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

assert_eq!(value, "b");
source

fn fold<R, Op, Init, IV>( self, count: R, op: Op, init: Init ) -> Fold<Self, Op, Init>
where R: RepetitionArgument, Init: Fn() -> IV, Op: Fn(IV, Self::Out) -> IV, Self: Sized,

Returns a parser that succeeds if it is able to match its input count times.

The funcion op is executed for each successful repetition. Its return value is used as an argument for its next invocation.

The function init determines what the argument to op will be the first time it is called.

.fold() is useful whenever you want invoke a parser multiple times and do something with the result of each invocation.

Here is a contrived example:

use parser_compose::{Parser, utf8_scalar};
use std::str::FromStr;

fn digit(input: &str) -> Option<(u8, &str)> {
    utf8_scalar(0x30..=0x39)
    .and_then(u8::from_str)
    .try_parse(input)
}

// We want to sum the digits in this string
let input = "8.8.2.4";

let sum_parser = (digit, ".".optional()).fold(4, |accum, curr| accum + curr.0, || 0u8);

let (sum, rest) = sum_parser.try_parse(input).unwrap();

assert_eq!(sum , 22);
assert!(rest.is_empty());
source

fn repeats<R>( self, count: R ) -> Fold<Self, RepeatsOperation<Self::Out>, RepeatsInit>
where Self: Sized, R: RepetitionArgument,

Returns a parser that succeeds if it is able to match its input count times, discarding any output along the way

use parser_compose::{Parser, utf8_scalar};

let valid_number = "123-456-7899";
let invalid_number = "123-3454-34";

let digit = utf8_scalar(0x30..=0x39);
let validator = (digit.repeats(3), "-", digit.repeats(3), "-", digit.repeats(4));

let (value, rest) = validator.try_parse(valid_number).unwrap();
assert_eq!(value, ((), "-", (), "-", ()));
assert_eq!(rest, "");

let res = validator.try_parse(invalid_number.into());
assert!(res.is_none());
source

fn accumulate<R>( self, count: R ) -> Fold<Self, AccumulateOperation<Self::Out>, AccumulateInit<Self::Out>>
where R: RepetitionArgument, Self: Sized,

Returns a parser that succeeds if it is able to match its input count times, accumulating output into a Vec along the way.

use parser_compose::Parser;

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

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

fn input(self) -> Input<Self>
where Self: Sized,

Returns a parser that outputs the slice of the input that was recognized.

Works very well with the .repeats() combinator as an alternative to .accumulate() if you want to avoid allocating a Vec.

Here is the same example from .accumulate(), this time using .input():

use parser_compose::Parser;

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

assert_eq!(value, "AAA");
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. If the original parser would have failed, the parser outputs a Some(None).

use parser_compose::Parser;

let msg = "a";

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

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

fn peek(self) -> Peek<Self>
where Self: Sized,

Returns a parser that never consumes any input regardless of its outcome. It 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".peek());

let (value, rest) = a_then_b.try_parse("abc".into()).unwrap();
// The peeked output is still returned, but is not consumed
assert_eq!(value, ("a", "b", "c"));
assert_eq!(rest, "c");

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

fn not(self) -> Not<Self>
where Self: Sized,

Returns a parser that succeeds if it was not able to recognize its 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());

let msg = "foobar";

let result = parser.try_parse(msg);

assert!(result.is_none());

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

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

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

Returns a parser that applies a falible function f to its output. The parser will return None if f fails.

use parser_compose::{Parser};

let msg = [98].as_slice();

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

assert_eq!("b", value);

Implementations on Foreign Types§

source§

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

Parser implementation for string slices

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 (value, rest) = "HE".try_parse(msg).unwrap();

assert_eq!(value, "HE");
assert_eq!(rest, "LLO");
§

type Out = &'pat str

source§

fn try_parse(&self, input: &'input str) -> Option<(Self::Out, &'input str)>

source§

impl<'p, 'i, T> Parser<&'i [T]> for &'p [T]
where T: PartialEq + Debug,

Parser implementation for slices

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).unwrap();


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

type Out = &'p [T]

source§

fn try_parse(&self, input: &'i [T]) -> Option<(Self::Out, &'i [T])>

source§

impl<In, P0, O0> Parser<In> for (P0,)
where P0: Parser<In, Out = 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

§

type Out = (O0,)

source§

fn try_parse(&self, ctx: In) -> Option<((O0,), In)>

source§

impl<In, P0, O0, P1, O1> Parser<In> for (P0, P1)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = 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

§

type Out = (O0, O1)

source§

fn try_parse(&self, ctx: In) -> Option<((O0, O1), In)>

source§

impl<In, P0, O0, P1, O1, P2, O2> Parser<In> for (P0, P1, P2)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = 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

§

type Out = (O0, O1, O2)

source§

fn try_parse(&self, ctx: In) -> Option<((O0, O1, O2), In)>

source§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3> Parser<In> for (P0, P1, P2, P3)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = 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§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4> Parser<In> for (P0, P1, P2, P3, P4)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = 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§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5> Parser<In> for (P0, P1, P2, P3, P4, P5)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = 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§

impl<In, P0, O0, P1, O1, P2, O2, P3, O3, P4, O4, P5, O5, P6, O6> Parser<In> for (P0, P1, P2, P3, P4, P5, P6)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = 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> for (P0, P1, P2, P3, P4, P5, P6, P7)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = O6>, P7: Parser<In, Out = 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> for (P0, P1, P2, P3, P4, P5, P6, P7, P8)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = O6>, P7: Parser<In, Out = O7>, P8: Parser<In, Out = 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> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = O6>, P7: Parser<In, Out = O7>, P8: Parser<In, Out = O8>, P9: Parser<In, Out = 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> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = O6>, P7: Parser<In, Out = O7>, P8: Parser<In, Out = O8>, P9: Parser<In, Out = O9>, P10: Parser<In, Out = 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> for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)
where P0: Parser<In, Out = O0>, P1: Parser<In, Out = O1>, P2: Parser<In, Out = O2>, P3: Parser<In, Out = O3>, P4: Parser<In, Out = O4>, P5: Parser<In, Out = O5>, P6: Parser<In, Out = O6>, P7: Parser<In, Out = O7>, P8: Parser<In, Out = O8>, P9: Parser<In, Out = O9>, P10: Parser<In, Out = O10>, P11: Parser<In, Out = 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<'i> Parser<&'i str> for Utf8Scalar

§

type Out = &'i str

source§

impl<'i> Parser<&'i [u8]> for Byte

§

type Out = &'i [u8]

source§

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

§

type Out = U

source§

impl<In, Out, F> Parser<In> for F
where F: Fn(In) -> Option<(Out, In)>,

Parser implementation for functions

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

Fn(In) -> Option<(Out, In)>

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

§

type Out = Out

source§

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

§

type Out = Out

source§

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

§

type Out = Option<Out>

source§

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

§

type Out = Out

source§

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

§

type Out = Out

source§

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

§

type Out = M

source§

impl<In, Out, P, Operation, Init, Accum> Parser<In> for Fold<P, Operation, Init>
where P: Parser<In, Out = Out>, Init: Fn() -> Accum, Operation: Fn(Accum, Out) -> Accum, In: Clone,

§

type Out = Accum