kalosm_sample/structured_parser/
map.rs

1use std::{fmt::Debug, marker::PhantomData};
2
3use crate::{CreateParserState, ParseStatus, Parser};
4
5/// A parser that maps the output of another parser.
6pub struct MapOutputParser<P: Parser, O, F = fn(<P as Parser>::Output) -> O> {
7    pub(crate) parser: P,
8    pub(crate) map: F,
9    pub(crate) _output: std::marker::PhantomData<O>,
10}
11
12impl<P: Parser + Debug, O, F> Debug for MapOutputParser<P, O, F> {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        self.parser.fmt(f)
15    }
16}
17
18impl<P: Parser + PartialEq, O, F: PartialEq> PartialEq for MapOutputParser<P, O, F> {
19    fn eq(&self, other: &Self) -> bool {
20        self.parser == other.parser && self.map == other.map
21    }
22}
23
24impl<P: Parser + Clone, O, F: Clone> Clone for MapOutputParser<P, O, F> {
25    fn clone(&self) -> Self {
26        Self {
27            parser: self.parser.clone(),
28            map: self.map.clone(),
29            _output: PhantomData,
30        }
31    }
32}
33
34impl<P: CreateParserState, O: Clone, F: Fn(P::Output) -> O> CreateParserState
35    for MapOutputParser<P, O, F>
36{
37    fn create_parser_state(&self) -> <Self as Parser>::PartialState {
38        self.parser.create_parser_state()
39    }
40}
41
42impl<P: Parser, O: Clone, F: Fn(P::Output) -> O> Parser for MapOutputParser<P, O, F> {
43    type Output = O;
44    type PartialState = P::PartialState;
45
46    fn parse<'a>(
47        &self,
48        state: &Self::PartialState,
49        input: &'a [u8],
50    ) -> crate::ParseResult<ParseStatus<'a, Self::PartialState, Self::Output>> {
51        let result = self.parser.parse(state, input)?;
52        match result {
53            ParseStatus::Finished { result, remaining } => Ok(ParseStatus::Finished {
54                result: (self.map)(result),
55                remaining,
56            }),
57            ParseStatus::Incomplete {
58                new_state,
59                required_next,
60            } => Ok(ParseStatus::Incomplete {
61                new_state,
62                required_next,
63            }),
64        }
65    }
66}