Trait combine::Parser [] [src]

pub trait Parser {
    type Input: Stream;
    type Output;
    fn parse(&mut self,
             input: Self::Input)
             -> Result<(Self::Output, Self::Input), ParseError<Self::Input>> { ... } fn parse_stream(&mut self,
                    input: Self::Input)
                    -> ParseResult<Self::Output, Self::Input> { ... } fn parse_stream_consumed(&mut self,
                             input: Self::Input)
                             -> ConsumedResult<Self::Output, Self::Input> { ... } fn parse_lazy(&mut self,
                  input: Self::Input)
                  -> ConsumedResult<Self::Output, Self::Input> { ... } fn add_error(&mut self, _error: &mut ParseError<Self::Input>) { ... } fn by_ref(&mut self) -> &mut Self where Self: Sized { ... } fn with<P2>(self, p: P2) -> With<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input> { ... } fn skip<P2>(self, p: P2) -> Skip<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input> { ... } fn and<P2>(self, p: P2) -> (Self, P2) where Self: Sized, P2: Parser<Input=Self::Input> { ... } fn or<P2>(self, p: P2) -> Or<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input, Output=Self::Output> { ... } fn then<N, F>(self, f: F) -> Then<Self, F> where Self: Sized,
              F: FnMut(Self::Output) -> N,
              N: Parser<Input=Self::Input>
{ ... } fn map<F, B>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(Self::Output) -> B { ... } fn flat_map<F, B>(self, f: F) -> FlatMap<Self, F> where Self: Sized,
              F: FnMut(Self::Output) -> Result<B, ParseError<Self::Input>>
{ ... } fn message<S>(self, msg: S) -> Message<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>> { ... } fn expected<S>(self, msg: S) -> Expected<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>> { ... } fn and_then<F, O, E>(self, f: F) -> AndThen<Self, F> where Self: Sized,
              F: FnMut(Self::Output) -> Result<O, E>,
              E: Into<Error<Self::Input::Item, Self::Input::Range>>
{ ... } fn iter(self, input: Self::Input) -> Iter<Self> where Self: Sized { ... } fn boxed<'a>(self)
                 -> Box<Parser<Input=Self::Input, Output=Self::Output> + 'a> where Self: Sized + 'a { ... } }

By implementing the Parser trait a type says that it can be used to parse an input stream into the type Output.

All methods have a default implementation but there needs to be at least an implementation of parse_stream orparse_lazy. If parse_lazy is implemented an implementation of add_error is also recommended to improve error reporting.

Associated Types

The type which is take as input for the parser. The type must implement the Stream trait which allows the parser to read item from the type.

The type which is returned if the parser is successful.

Provided Methods

Entrypoint of the parser Takes some input and tries to parse it returning a ParseResult

Parses using the stream input by calling Stream::uncons one or more times On success returns Ok((value, new_state)) on failure it returns Err(error)

Parses using the stream input by calling Stream::uncons one or more times On success returns Ok((value, new_state)) on failure it returns Err(error)

Specialized version of parse_stream where the parser does not need to add an error to the ParseError when it does not consume any input before encountering the error. Instead the error can be added later through the add_error method

Adds the first error that would normally be returned by this parser if it failed

Borrows a parser instead of consuming it.

Used to apply parser combinators on self without losing ownership.

fn test() -> ParseResult<(char, char), &'static str> {
    let mut p = digit();
    let ((d, _), input) = try!((p.by_ref(), letter()).parse_stream("1a23"));
    let (d2, input) = try!(input.combine(|input| p.parse_stream(input)));
    Ok(((d, d2), input))
}

fn main() {
    assert_eq!(test(), Ok((('1', '2'), Consumed::Consumed("3"))));
}

Discards the value of the self parser and returns the value of p Fails if any of the parsers fails

let result = digit()
    .with(token('i'))
    .parse("9i")
    .map(|x| x.0);
assert_eq!(result, Ok('i'));

Discards the value of the p parser and returns the value of self Fails if any of the parsers fails

let result = digit()
    .skip(token('i'))
    .parse("9i")
    .map(|x| x.0);
assert_eq!(result, Ok('9'));

Parses with self followed by p Succeeds if both parsers succeed, otherwise fails Returns a tuple with both values on success

let result = digit()
    .and(token('i'))
    .parse("9i")
    .map(|x| x.0);
assert_eq!(result, Ok(('9', 'i')));

Returns a parser which attempts to parse using self. If self fails without consuming any input it tries to consume the same input using p.

let mut parser = string("let")
    .or(digit().map(|_| "digit"))
    .or(string("led"));
assert_eq!(parser.parse("let"), Ok(("let", "")));
assert_eq!(parser.parse("1"), Ok(("digit", "")));
assert!(parser.parse("led").is_err());

let mut parser2 = string("two").or(string("three"));
// Fails as the parser for "two" consumes the first 't' before failing
assert!(parser2.parse("three").is_err());

// Use 'try' to make failing parsers always act as if they have not consumed any input
let mut parser3 = try(string("two")).or(try(string("three")));
assert_eq!(parser3.parse("three"), Ok(("three", "")));

Parses using self and then passes the value to f which returns a parser used to parse the rest of the input

let result = digit()
    .then(|d| parser(move |input| {
            // Force input to be a &str
            let _: &str = input;
        if d == '9' {
            Ok((9, Consumed::Empty(input)))
        }
        else {
            let position = input.position();
            let err = ParseError::new(position, Error::Message("Not a nine".into()));
            Err((Consumed::Empty(err)))
        }
    }))
    .parse("9");
assert_eq!(result, Ok((9, "")));

Uses f to map over the parsed value

let result = digit()
    .map(|c| c == '9')
    .parse("9")
    .map(|x| x.0);
assert_eq!(result, Ok(true));

Uses f to map over the output of self. If f returns an error the parser fails.

let result = take(4)
    .flat_map(|bs| many(digit()).parse(bs).map(|t| t.0))
    .parse("12abcd");
assert_eq!(result, Ok((String::from("12"), "cd")));

Parses with self and if it fails, adds the message msg to the error

let result = token('9')
    .message("Not a nine")
    .parse(State::new("8"));
assert_eq!(result, Err(ParseError {
    position: <char as Positioner>::start(),
    errors: vec![
        Error::Unexpected('8'.into()),
        Error::Expected('9'.into()),
        Error::Message("Not a nine".into())
    ]
}));

Parses with self and if it fails without consuming any input any expected errors are replaced by msg. msg is then used in error messages as "Expected msg".

let result = token('9')
    .expected("nine")
    .parse(State::new("8"));
assert_eq!(result, Err(ParseError {
    position: <char as Positioner>::start(),
    errors: vec![Error::Unexpected('8'.into()), Error::Expected("nine".into())]
}));

Parses with self and applies f on the result if self parses successfully f may optionally fail with an error which is automatically converted to a ParseError

let mut parser = many1(digit())
    .and_then(|s: String| s.parse::<i32>());
let result = parser.parse("1234");
assert_eq!(result, Ok((1234, "")));
let err = parser.parse("abc");
assert!(err.is_err());

Creates an iterator from a parser and a state. Can be used as an alternative to many when collecting directly into a FromIterator type is not desirable

let mut buffer = String::new();
let number = parser(|input| {
    buffer.clear();
    let mut iter = digit().iter(input);
    buffer.extend(&mut iter);
    let i = buffer.parse::<i32>().unwrap();
    iter.into_result(i)
});
let result = sep_by(number, char(','))
    .parse("123,45,6");
assert_eq!(result, Ok((vec![123, 45, 6], "")));

Turns the parser into a trait object by putting it in a Box. Can be used to easily return parsers from functions without naming the type.

fn test<'input, F>(c: char, f: F) ->  Box<Parser<Input = &'input str, Output = (char, char)>>
    where F: FnMut(char) -> bool + 'static
{
    (token(c), satisfy(f)).boxed()
}
let result = test('a', |c| c >= 'a' && c <= 'f')
    .parse("ac");
assert_eq!(result, Ok((('a', 'c'), "")));

Implementors