Trait parsimonious::Stateful [] [src]

pub trait Stateful<S> {
    type Output;
    fn parse(self, value: S) -> ParseResult<Self, S>
    where
        Self: Sized
; fn done(self) -> Self::Output
    where
        Self: Sized
; fn boxable(self) -> BoxableParser<Self>
    where
        Self: Sized
, { ... } }

A trait for stateful parsers.

Stateful parsers are typically constructed by calling the init method of a stateless parser, for example:

let stateless = character(char::is_alphanumeric).star(String::new);
let stateful = stateless.init();

Here, stateless is a Committed<&str,Output=String>, and stateful is a Stateful<&str,Output=String>.

The reason for distinguishing between stateful and stateless parsers is that stateless parsers are usually copyable, whereas stateful parsers are usually not (they may, for example, have created and partially filled some buffers). Copying parsers is quite common, for example:

fn mk_err() -> Result<char,String> { Err(String::from("Expecting a digit")) }
let DIGIT = character(char::is_numeric).map(Ok).or_emit(mk_err);
let TWO_DIGITS = DIGIT.try_and_then_try(DIGIT);
match TWO_DIGITS.init().parse("123") {
   Done("3",result) => assert_eq!(result,Ok(('1','2'))),
   _ => panic!("Can't happen"),
}

Associated Types

The type of the data being produced by the parser.

Required Methods

Provides data to the parser.

If parser: Stateful<S,Output=T>, then parser.parse(data) either:

  • returns Done(rest, result) where rest: S is any remaining input, and result: T is the parsed output, or
  • returns Continue(rest,parsing) where parsing: Self is the new state of the parser.

For example:

let parser = character(char::is_alphabetic).star(String::new);
let stateful = parser.init();
match stateful.parse("abc") {
    Continue("",parsing) => match parsing.parse("def!") {
        Done("!",result) => assert_eq!(result,"abcdef"),
        _ => panic!("can't happen"),
    },
    _ => panic!("can't happen"),
}

Note that parser.parse(data) consumes both the parser and the data. In particular, the parser is no longer available, so the following does not typecheck:

let parser = character(char::is_alphabetic).star(String::new);
let stateful = parser.init();
stateful.parse("abc");
stateful.parse("def!");

This helps with parser safety, as it stops a client from calling parse after a a stateful parser has finished.

Tells the parser that it will not receive any more data.

If parser: Stateful<S,Output=T>, then parser.done() returns a result of type T for example:

let parser = character(char::is_alphabetic).star(String::new);
let stateful = parser.init();
match stateful.parse("abc") {
    Continue("",parsing) => match parsing.parse("def") {
        Continue("",parsing) => assert_eq!(parsing.done(),"abcdef"),
        _ => panic!("can't happen"),
    },
    _ => panic!("can't happen"),
}

Note that parser.done() consumes the parser. In particular, the parser is no longer available, so the following does not typecheck:

let parser = character(char::is_alphabetic).star(String::new);
let stateful = parser.init();
stateful.done();
stateful.parse("def!");

This helps with parser safety, as it stops a client from calling parse after a a stateful parser has finished.

Provided Methods

Make this parser boxable.

Implementors