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,
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 andresult: Output
is the parsed output, or - returns
Continue(parsing)
whereparsing: 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,
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,
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
impl<P, F, Ch, Str, Output> Stateful<Ch, Str, Output> for Map<P, F> where
P: StatefulInfer<Ch, Str>,
F: Function<P::Output, Output = Output>,impl<P, F, Ch, Str, Output> Stateful<Ch, Str, Output> for VariantMap<P, F> where
P: Stateful<Ch, Str, F::Input>,
F: VariantFunction<Output>,impl<PState, Q, PStaticOutput, QState, Ch, Str, POutput, QOutput> Stateful<Ch, Str, (POutput, QOutput)> for AndThenState<PState, Q, PStaticOutput, QState> where
PState: Stateful<Ch, Str, POutput>,
Q: Committed<Ch, Str, QOutput, State = QState>,
QState: Stateful<Ch, Str, QOutput>,
POutput: Downcast<PStaticOutput>,
PStaticOutput: 'static + Upcast<POutput>,impl<P, Q, Ch, Str, Output> Stateful<Ch, Str, Output> for OrElseState<P, Q> where
P: Stateful<Ch, Str, Output>,
Q: Stateful<Ch, Str, Output>,impl<P, PState, T, Ch, Str> Stateful<Ch, Str, T> for StarState<P, PState, T> where
P: Copy + UncommittedInfer<Ch, Str, State = PState>,
PState: Stateful<Ch, Str, P::Output>,
T: Consumer<P::Output>,
Str: PeekableIterator,impl<P, Ch, Str, Output> Stateful<Ch, Str, Option<Output>> for Opt<P> where
P: Stateful<Ch, Str, Output>,impl<P, Ch, Str> Stateful<Ch, Str, ()> for Discard<P> where
P: StatefulInfer<Ch, Str>,impl<F, Ch, Str> Stateful<Ch, Str, F::Output> for Emit<F> where
F: Factory,impl<Ch, Str> Stateful<Ch, Str, Ch> for CharacterState
impl<Ch, Str> Stateful<Ch, Str, Option<Ch>> for AnyCharacter where
Str: Iterator<Item = Ch>,impl<'a, P> Stateful<char, Chars<'a>, Cow<'a, str>> for BufferedState<P> where
P: StatefulInfer<char, Chars<'a>>,impl<P: ?Sized, Ch, Str, Output> Stateful<Ch, Str, Output> for Box<P> where
P: Boxable<Ch, Str, Output>,impl<P, PState, Ch, Str, Output> Stateful<Ch, Str, Output> for InState<P, PState> where
PState: Stateful<Ch, Str, Output>,