Trait parsell::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(_: 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().parse("123") { Done("3",result) => assert_eq!(result,Ok(('1','2'))), _ => panic!("Can't happen"), }
Associated Types
type Output
The type of the data being produced by the parser.
Required Methods
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)
whererest: S
is any remaining input, andresult: T
is the parsed output, or - returns
Continue(rest,parsing)
whereparsing: 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.
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
fn boxable(self) -> BoxableParser<Self> where Self: Sized
Make this parser boxable.
Implementors
impl<P, F, S, T> Stateful<S> for MapStatefulParser<P, F> where P: Stateful<S, Output=T>, F: Function<T>
impl<P, Q, S> Stateful<S> for AndThenStatefulParser<P, Q, P::Output> where P: Stateful<S>, Q: Stateful<S>
impl<P, Q, S> Stateful<S> for OrElseStatefulParser<P, Q> where P: Stateful<S>, Q: Stateful<S, Output=P::Output>
impl<P, Q, S> Stateful<S> for OrElseCommittedParser<P, P::State, Q> where P: Uncommitted<S>, Q: Stateful<S, Output=P::Output>
impl<P, F, S> Stateful<S> for OrEmitStatefulParser<P, F, P::State> where P: Uncommitted<S>, F: Factory<Output=P::Output>
impl<P, T, S> Stateful<S> for StarStatefulParser<P, P::State, T> where P: Copy + Uncommitted<S>, T: Consumer<P::Output>
impl<T, S> Stateful<S> for ImpossibleStatefulParser<T>
impl<'a> Stateful<&'a str> for AnyCharacterParser
impl<I> Stateful<I> for AnyTokenParser where I: Iterator
impl<'a, P> Stateful<&'a str> for BufferedStatefulParser<P> where P: Stateful<&'a str>
impl<P: ?Sized, S> Stateful<S> for Box<P> where P: Boxable<S>
impl<P, Q, S, T> Stateful<S> for PipeStateful<P, P::State, Q> where P: Copy + Committed<S>, Q: for<'a> Stateful<Peekable<&'a mut IterParser<P, P::State, S>>, Output=T>