somen/parser/iterable/combinator/
flatten.rs1use core::pin::Pin;
2use core::task::{Context, Poll};
3use futures_core::ready;
4
5use crate::error::{Error, PolledResult, Status};
6use crate::parser::iterable::IterableParser;
7use crate::parser::utils::merge_errors;
8use crate::stream::Positioned;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct Flatten<P> {
15 inner: P,
16}
17
18impl<P> Flatten<P> {
19 #[inline]
21 pub fn new(inner: P) -> Self {
22 Self { inner }
23 }
24
25 #[inline]
27 pub fn into_inner(self) -> P {
28 self.inner
29 }
30}
31
32crate::parser_state! {
33 pub struct FlattenState<I, P: IterableParser; T> {
34 inner: P::State,
35 iter: Option<T>,
36 error: Option<Error<I::Locator>>,
37 }
38}
39
40impl<P, I> IterableParser<I> for Flatten<P>
41where
42 P: IterableParser<I>,
43 P::Item: IntoIterator,
44 I: Positioned + ?Sized,
45{
46 type Item = <P::Item as IntoIterator>::Item;
47 type State = FlattenState<I, P, <P::Item as IntoIterator>::IntoIter>;
48
49 fn poll_parse_next(
50 &mut self,
51 mut input: Pin<&mut I>,
52 cx: &mut Context<'_>,
53 state: &mut Self::State,
54 ) -> PolledResult<Option<Self::Item>, I> {
55 Poll::Ready(Ok(loop {
56 if let Some(iter) = &mut state.iter {
57 if let Some(val) = iter.next() {
58 break Status::Success(Some(val), state.error());
59 }
60 }
61
62 match ready!(self
63 .inner
64 .poll_parse_next(input.as_mut(), cx, &mut state.inner)?)
65 {
66 Status::Success(Some(iter), err) => {
67 state.iter = Some(iter.into_iter());
68 merge_errors(&mut state.error, err);
69 }
70 Status::Success(None, err) => {
71 merge_errors(&mut state.error, err);
72 break Status::Success(None, state.error());
73 }
74 Status::Failure(err, false) => {
75 merge_errors(&mut state.error, Some(err));
76 break Status::Failure(state.error().unwrap(), false);
77 }
78 Status::Failure(err, true) => break Status::Failure(err, true),
79 }
80 }))
81 }
82}