Trait Stateful

Source
pub trait Stateful<S> {
    type Output;

    // Required methods
    fn parse(self, value: S) -> ParseResult<Self, S>
       where Self: Sized;
    fn done(self) -> Self::Output
       where Self: Sized;

    // Provided method
    fn boxable(self) -> BoxableParser<Self>
       where Self: Sized { ... }
}
Expand description

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"),
}

Required Associated Types§

Source

type Output

The type of the data being produced by the parser.

Required Methods§

Source

fn parse(self, value: S) -> ParseResult<Self, S>
where Self: Sized,

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.

Source

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

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§

Source

fn boxable(self) -> BoxableParser<Self>
where Self: Sized,

Make this parser boxable.

Implementations on Foreign Types§

Source§

impl<P, S> Stateful<S> for Box<P>
where P: Boxable<S> + ?Sized,

Source§

type Output = <P as Boxable<S>>::Output

Source§

fn parse(self, value: S) -> ParseResult<Self, S>

Source§

fn done(self) -> Self::Output

Implementors§

Source§

impl<'a, P> Stateful<&'a str> for BufferedStatefulParser<P>
where P: Stateful<&'a str>,

Source§

type Output = Cow<'a, str>

Source§

impl<P, F, S> Stateful<S> for OrEmitStatefulParser<P, F, P::State>
where P: Uncommitted<S>, F: Factory<Output = P::Output>,

Source§

impl<P, F, S, T> Stateful<S> for MapStatefulParser<P, F>
where P: Stateful<S, Output = T>, F: Function<T>,

Source§

type Output = <F as Function<T>>::Output

Source§

impl<P, Q, S> Stateful<S> for AndThenStatefulParser<P, Q, P::Output>
where P: Stateful<S>, Q: Stateful<S>,

Source§

type Output = (<P as Stateful<S>>::Output, <Q as Stateful<S>>::Output)

Source§

impl<P, Q, S> Stateful<S> for OrElseStatefulParser<P, Q>
where P: Stateful<S>, Q: Stateful<S, Output = P::Output>,

Source§

type Output = <P as Stateful<S>>::Output

Source§

impl<P, Q, S> Stateful<S> for PipeStateful<P, P::State, Q>
where P: Copy + Committed<S>, Q: Stateful<Peekable<IterParser<P, P::State, S>>>,

Source§

type Output = <Q as Stateful<Peekable<IterParser<P, <P as Committed<S>>::State, S>>>>::Output

Source§

impl<P, T, S> Stateful<S> for StarStatefulParser<P, P::State, T>
where P: Copy + Uncommitted<S>, T: Consumer<P::Output>,

Source§

impl<T, S> Stateful<S> for ImpossibleStatefulParser<T>