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
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,
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,
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,
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, 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, 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> Stateful<S> for PipeStateful<P, P::State, Q> where
P: Copy + Committed<S>,
Q: Stateful<Peekable<IterParser<P, P::State, S>>>,