fabparse/
combinator.rs

1use std::{error::Error, marker::PhantomData};
2
3use crate::{sequence::Sequence, Parser, ParserError, ParserType};
4
5pub struct ParserMap<P, I: ?Sized, M, E, F> {
6    pub parser: P,
7    pub func: F,
8    pub phantom_i: PhantomData<I>,
9    pub phantom_e: PhantomData<E>,
10    pub phantom_m: PhantomData<M>,
11}
12pub struct ParserMapT<PType, M> {
13    phantom_ptype: PhantomData<PType>,
14    phantom_m: PhantomData<M>,
15}
16impl<'a, P, M, I, O, E: ParserError, PType, F> Parser<'a, I, O, E, ParserMapT<PType, M>>
17    for ParserMap<P, I, M, E, F>
18where
19    P: Parser<'a, I, M, E, PType>,
20    F: Fn(M) -> O,
21    I: ?Sized + Sequence,
22{
23    fn fab(&self, input: &mut &'a I) -> Result<O, E> {
24        match self.parser.fab(input) {
25            Ok(res) => Ok((self.func)(res)),
26            Err(mut err) => {
27                err.add_context(*input, ParserType::Map);
28                Err(err)
29            }
30        }
31    }
32}
33
34#[derive(Clone, Debug)]
35pub struct ParserTryMap<P, I: ?Sized, M, E, F> {
36    pub parser: P,
37    pub func: F,
38    pub phantom_i: PhantomData<I>,
39    pub phantom_e: PhantomData<E>,
40    pub phantom_m: PhantomData<M>,
41}
42
43pub struct ParserTryMapOption<PType, M> {
44    phantom_ptype: PhantomData<PType>,
45    phantom_m: PhantomData<M>,
46}
47impl<'a, P, M, I: ?Sized + Sequence, O, E: ParserError, PType, F>
48    Parser<'a, I, O, E, ParserTryMapOption<PType, M>> for ParserTryMap<P, I, M, E, F>
49where
50    P: Parser<'a, I, M, E, PType>,
51    F: Fn(M) -> Option<O>,
52{
53    fn fab(&self, input: &mut &'a I) -> Result<O, E> {
54        let checkpoint = *input;
55        match self.parser.fab(input) {
56            Ok(res) => {
57                let func_result = (self.func)(res);
58                func_result.ok_or_else(|| {
59                    *input = checkpoint;
60                    E::from_parser_error(*input, ParserType::TryMap)
61                })
62            }
63            Err(mut err) => {
64                err.add_context(checkpoint, ParserType::Map);
65                Err(err)
66            }
67        }
68    }
69}
70pub struct ParserTryMapResult<PType, M, FErr> {
71    phantom_ptype: PhantomData<PType>,
72    phantom_m: PhantomData<M>,
73    phantom_ferr: PhantomData<FErr>,
74}
75impl<'a, P, M, I, O, E: ParserError, PType, FErr, F>
76    Parser<'a, I, O, E, ParserTryMapResult<PType, M, FErr>> for ParserTryMap<P, I, M, E, F>
77where
78    P: Parser<'a, I, M, E, PType>,
79    FErr: Error + Send + Sync + 'static,
80    F: Fn(M) -> Result<O, FErr>,
81    I: ?Sized + Sequence,
82{
83    fn fab(&self, input: &mut &'a I) -> Result<O, E> {
84        let checkpoint = *input;
85        match self.parser.fab(input) {
86            Ok(res) => {
87                let func_result = (self.func)(res);
88                func_result.map_err(|err| {
89                    *input = checkpoint;
90                    E::from_external_error(*input, ParserType::TryMap, err)
91                })
92            }
93            Err(mut err) => {
94                err.add_context(checkpoint, ParserType::Map);
95                Err(err)
96            }
97        }
98    }
99}
100
101#[derive(Clone, Debug)]
102pub struct Opt<P> {
103    pub parser: P,
104}
105
106impl<'a, I: ?Sized, O, E: ParserError, ParserType, P> Parser<'a, I, Option<O>, E, Opt<ParserType>>
107    for Opt<P>
108where
109    P: Parser<'a, I, O, E, ParserType>,
110{
111    fn fab(&self, input: &mut &'a I) -> Result<Option<O>, E> {
112        match self.parser.fab(input) {
113            Ok(out) => Ok(Some(out)),
114            Err(_) => Ok(None),
115        }
116    }
117}
118#[derive(Clone, Debug)]
119pub struct TakeNot<P> {
120    pub parser: P,
121}
122
123pub struct TakeNotParser<P, O> {
124    pub parser: PhantomData<P>,
125    pub out: PhantomData<O>,
126}
127impl<'a, I, O, E: ParserError, ParType, P, Item> Parser<'a, I, Item, E, TakeNotParser<ParType, O>>
128    for TakeNot<P>
129where
130    P: Parser<'a, I, O, E, ParType>,
131    I: ?Sized + Sequence<Item = Item>,
132{
133    fn fab(&self, input: &mut &'a I) -> Result<Item, E> {
134        let checkpoint = *input;
135        match self.parser.fab(input) {
136            Ok(_) => {
137                *input = checkpoint;
138                Err(E::from_parser_error(*input, ParserType::TakeNot))
139            }
140            Err(_) => {
141                *input = checkpoint;
142                match input.try_split_front() {
143                    Some((first, rest)) => {
144                        *input = rest;
145                        Ok(first)
146                    }
147                    None => Err(E::from_parser_error(*input, ParserType::TakeNot)),
148                }
149            }
150        }
151    }
152}
153#[derive(Clone, Debug)]
154pub struct Value<P, V, I: ?Sized, O, E> {
155    pub parser: P,
156    pub value: V,
157    pub phantom_i: PhantomData<I>,
158    pub phantom_o: PhantomData<O>,
159    pub phantom_e: PhantomData<E>,
160}
161
162pub struct ValueParser<P, O> {
163    pub parser: PhantomData<P>,
164    pub out: PhantomData<O>,
165}
166impl<'a, I, O, E: ParserError, ParType, P, V> Parser<'a, I, V, E, ValueParser<ParType, O>>
167    for Value<P, V, I, O, E>
168where
169    P: Parser<'a, I, O, E, ParType>,
170    I: ?Sized + Sequence,
171    V: Clone,
172{
173    fn fab(&self, input: &mut &'a I) -> Result<V, E> {
174        match self.parser.fab(input) {
175            Ok(_) => Ok(self.value.clone()),
176            Err(mut err) => {
177                err.add_context(*input, ParserType::Map);
178                Err(err)
179            }
180        }
181    }
182}