somen/parser/iterable/combinator/
last.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::parser::Parser;
9use crate::stream::Positioned;
10
11#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct Last<P> {
16 inner: P,
17}
18
19impl<P> Last<P> {
20 #[inline]
22 pub fn new(inner: P) -> Self {
23 Self { inner }
24 }
25
26 #[inline]
28 pub fn into_inner(self) -> P {
29 self.inner
30 }
31}
32
33crate::parser_state! {
34 pub struct LastState<I, P: IterableParser> {
35 inner: P::State,
36 output: Option<P::Item>,
37 error: Option<Error<I::Locator>>,
38 }
39}
40
41impl<P, I> Parser<I> for Last<P>
42where
43 P: IterableParser<I>,
44 I: Positioned + ?Sized,
45{
46 type Output = Option<P::Item>;
47 type State = LastState<I, P>;
48
49 fn poll_parse(
50 &mut self,
51 mut input: Pin<&mut I>,
52 cx: &mut Context<'_>,
53 state: &mut Self::State,
54 ) -> PolledResult<Self::Output, I> {
55 Poll::Ready(Ok(loop {
56 match ready!(self
57 .inner
58 .poll_parse_next(input.as_mut(), cx, &mut state.inner)?)
59 {
60 Status::Success(Some(val), err) => {
61 state.output = Some(val);
62 merge_errors(&mut state.error, err);
63 }
64 Status::Success(None, err) => {
65 merge_errors(&mut state.error, err);
66 break Status::Success(state.output(), state.error());
67 }
68 Status::Failure(err, false) => {
69 merge_errors(&mut state.error, Some(err));
70 break Status::Failure(state.error().unwrap(), false);
71 }
72 Status::Failure(err, true) => break Status::Failure(err, true),
73 }
74 }))
75 }
76}