Trait parsell::Stateful [] [src]

pub trait Stateful<Ch, Str, Output> {
    fn more(self, string: &mut Str) -> ParseResult<Self, Output> where Self: Sized;
    fn done(self) -> Output where Self: Sized;

    fn last(self, string: &mut Str) -> Output where Self: Sized { ... }
}

A trait for stateful parsers.

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

let stateless = character(char::is_alphanumeric).star(String::new);
match stateless.init_str("abc").unwrap() {
   Continue(stateful) => (),
   _ => panic!("Can't happen"),
}

Here, stateless is a Committed<char, Chars<'a>, String>, and stateful is a Stateful<char, Chars<'a>, 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(_: Option<char>) -> Result<char,String> { Err(String::from("Expecting a digit")) }
let DIGIT = character(char::is_numeric).map(Ok).or_else(CHARACTER.map(mk_err));
let TWO_DIGITS = DIGIT.try_and_then_try(DIGIT);
match TWO_DIGITS.init_str("123").unwrap() {
   Done(result) => assert_eq!(result, Ok(('1','2'))),
   _ => panic!("Can't happen"),
}

Required Methods

fn more(self, string: &mut Str) -> ParseResult<Self, Output> where Self: Sized

Provides data to the parser.

If parser: Stateful<Ch, Str, Output> and data: Str, then parser.parse(&mut data) either:

  • returns Done(result) where and result: Output is the parsed output, or
  • returns Continue(parsing) where parsing: Self is the new state of the parser.

For example:

let parser = character(char::is_alphabetic).star(String::new);
let data1 = "ab";
let data2 = "cd";
let data3 = "ef!";
match parser.init(&mut data1.chars()).unwrap() {
    Continue(stateful) => match stateful.more(&mut data2.chars()) {
        Continue(stateful) => match stateful.more(&mut data3.chars()) {
            Done(result) => assert_eq!(result, "abcdef"),
            _ => panic!("can't happen"),
        },
        _ => panic!("can't happen"),
    },
    _ => panic!("can't happen"),
}

Note that parser.parse(data) consumes the parser, but borrows the data mutably.

fn done(self) -> Output where Self: Sized

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

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

let parser = character(char::is_alphabetic).star(String::new);
let data1 = "ab";
let data2 = "cd";
let data3 = "ef";
match parser.init(&mut data1.chars()).unwrap() {
    Continue(stateful) => match stateful.more(&mut data2.chars()) {
        Continue(stateful) => assert_eq!(stateful.last(&mut data3.chars()), "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);
match parser.init_str("abc").unwrap() {
    Continue(parsing) => {
        parsing.done();
        parsing.more_str("def!");
    }
}

This helps with parser safety, as it stops a client from calling more after done.

Provided Methods

fn last(self, string: &mut Str) -> Output where Self: Sized

Provides the last data to the parser.

If parser: StatefulInfer<Ch, Str> and data: Str, then parser.last(&mut data) calls parser.more(&mut data), then calls done() if the parser continues.

Implementors