somen/parser/iterable/generator/
times.rs1use 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#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct Times<P> {
14 inner: P,
15 count: usize,
16}
17
18impl<P> Times<P> {
19 #[inline]
21 pub fn new(inner: P, count: usize) -> Self {
22 Self { inner, count }
23 }
24
25 #[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 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}