somen/parser/wrapper/
satisfy.rs1use core::pin::Pin;
2use core::task::Context;
3
4use crate::error::{Error, Expects, PolledResult, Status};
5use crate::parser::Parser;
6use crate::stream::Positioned;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct Satisfy<P, F> {
13 inner: P,
14 f: F,
15}
16
17impl<P, F> Satisfy<P, F> {
18 #[inline]
20 pub fn new(inner: P, f: F) -> Self {
21 Self { inner, f }
22 }
23
24 #[inline]
26 pub fn into_inner(self) -> P {
27 self.inner
28 }
29}
30
31crate::parser_state! {
32 pub struct SatisfyState<I, P: Parser> {
33 inner: P::State,
34 #[opt(set = set_start)]
35 start: I::Locator,
36 }
37}
38
39impl<P, F, I> Parser<I> for Satisfy<P, F>
40where
41 P: Parser<I>,
42 F: FnMut(&P::Output) -> bool,
43 I: Positioned + ?Sized,
44{
45 type Output = P::Output;
46 type State = SatisfyState<I, P>;
47
48 fn poll_parse(
49 &mut self,
50 mut input: Pin<&mut I>,
51 cx: &mut Context<'_>,
52 state: &mut Self::State,
53 ) -> PolledResult<Self::Output, I> {
54 state.set_start(|| input.position());
55 self.inner
56 .poll_parse(input.as_mut(), cx, &mut state.inner)
57 .map_ok(|status| match status {
58 Status::Success(val, err) if (self.f)(&val) => Status::Success(val, err),
59 Status::Success(_, _) => Status::Failure(
60 Error {
61 expects: Expects::from("<condition>"),
62 position: state.start()..input.position(),
63 },
64 true,
65 ),
66 Status::Failure(err, exclusive) => Status::Failure(err, exclusive),
67 })
68 }
69}