somen/parser/iterable/generator/
times.rs

1use core::pin::Pin;
2use core::task::{Context, Poll};
3use futures_core::ready;
4
5use crate::error::{PolledResult, Status};
6use crate::parser::Parser;
7use crate::prelude::{Positioned, IterableParser};
8
9/// A iterable parser generated from method [`times`].
10///
11/// [`times`]: crate::parser::ParserExt::times
12#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct Times<P> {
14    inner: P,
15    count: usize,
16}
17
18impl<P> Times<P> {
19    /// Creates a new instance.
20    #[inline]
21    pub fn new(inner: P, count: usize) -> Self {
22        Self { inner, count }
23    }
24
25    /// Extracts the inner parser.
26    #[inline]
27    pub fn into_inner(self) -> P {
28        self.inner
29    }
30}
31
32crate::parser_state! {
33    pub struct TimesState<I, P: Parser> {
34        inner: P::State,
35        count: usize,
36    }
37}
38
39impl<P, I> IterableParser<I> for Times<P>
40where
41    P: Parser<I>,
42    I: Positioned + ?Sized,
43{
44    type Item = P::Output;
45    type State = TimesState<I, P>;
46
47    fn poll_parse_next(
48        &mut self,
49        mut input: Pin<&mut I>,
50        cx: &mut Context<'_>,
51        state: &mut Self::State,
52    ) -> PolledResult<Option<Self::Item>, I> {
53        // Return `None` if the number of items already reached `end_bound`.
54        if state.count >= self.count {
55            return Poll::Ready(Ok(Status::Success(None, None)));
56        }
57
58        Poll::Ready(Ok(
59            match ready!(self
60                .inner
61                .poll_parse(input.as_mut(), cx, &mut state.inner)?)
62            {
63                Status::Success(val, err) => {
64                    state.inner = Default::default();
65                    state.count += 1;
66                    Status::Success(Some(val), err)
67                }
68                Status::Failure(err, exclusive) => Status::Failure(err, exclusive),
69            },
70        ))
71    }
72
73    #[inline]
74    fn size_hint(&self) -> (usize, Option<usize>) {
75        (self.count, Some(self.count))
76    }
77}