gobble/
ptrait.rs

1use crate::err::{Expected, PErr};
2use crate::iter::LCChars;
3use crate::pull::PullParser;
4use crate::reader::EOI;
5
6pub type ParseRes<'a, V> = Result<(LCChars<'a>, V, Option<PErr<'a>>), PErr<'a>>;
7
8/// The core trait for parsing
9pub trait Parser: Sized {
10    type Out;
11    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, Self::Out>;
12
13    fn expected(&self) -> Expected {
14        Expected::ObOn(
15            std::any::type_name::<Self>(),
16            std::any::type_name::<Self::Out>(),
17        )
18    }
19    fn parse_s<'a>(&self, s: &'a str) -> Result<Self::Out, PErr<'a>> {
20        self.parse(&LCChars::str(s)).map(|(_, v, _)| v)
21    }
22
23    fn parse_sn<'a>(&self, s: &'a str) -> Result<(&'a str, Self::Out), PErr<'a>> {
24        self.parse(&LCChars::str(s))
25            .map(|(i, v, _)| (i.as_str(), v))
26    }
27    /// returns a parser that will combine the results of this and the given parser
28    /// into a tuple
29    fn then<P: Parser<Out = V2>, V2>(self, b: P) -> Then<Self, P> {
30        Then { a: self, b }
31    }
32
33    /// returns a Parser that will require the given parser completes, but ignores its result
34    /// useful for dropping brackets and whitespace
35    fn then_ig<P: Parser<Out = V2>, V2>(self, b: P) -> ThenIg<Self, P> {
36        ThenIg { a: self, b }
37    }
38    /// returns a Parser that will require this parser completes, but only return the
39    /// result of the given parser
40    /// useful for dropping brackets and whitespace etc
41    fn ig_then<P: Parser<Out = V2>, V2>(self, b: P) -> IgThen<Self, P> {
42        IgThen { a: self, b }
43    }
44    /// Returns a Parser that will try both child parsers, (A first) and return the first successfl
45    /// result
46    fn or<P: Parser<Out = Self::Out>>(self, p: P) -> Or<Self, P> {
47        Or { a: self, b: p }
48    }
49
50    /// Returns a Parser that converts the result of a successful parse to a different type.
51    /// Much like map on iterators and Result
52    fn map<F: Fn(Self::Out) -> V2, V2>(self, f: F) -> Map<Self, V2, F> {
53        Map { a: self, f }
54    }
55
56    /// Returns a Parser that converts the result of a successful parse to a different type.
57    /// however the map function can fail and return a result
58    /// The Error type should be err::ECode, this does not have line associated. That will
59    /// be attacked by the TryMap object
60    /// so this will pass that error up correctly
61    fn try_map<F: Fn(Self::Out) -> Result<V2, Expected>, V2>(self, f: F) -> TryMap<Self, V2, F> {
62        TryMap { a: self, f }
63    }
64
65    fn asv<R: Clone>(self, r: R) -> As<Self, R> {
66        As { a: self, r }
67    }
68
69    fn ig(self) -> As<Self, ()> {
70        self.asv(())
71    }
72
73    fn map_exp<F: Fn(Expected) -> Expected>(self, f: F) -> MapExp<Self, F> {
74        MapExp { p: self, f }
75    }
76
77    fn brk(self) -> Break<Self> {
78        Break { p: self }
79    }
80
81    fn pull<'a>(self, s: &'a str) -> PullParser<'a, Self, EOI> {
82        PullParser::new(self, s)
83    }
84
85    fn pull_to<'a, E: Parser>(self, end: E, s: &'a str) -> PullParser<'a, Self, E> {
86        PullParser::with_end(self, end, s)
87    }
88}
89
90impl<V, F: for<'a> Fn(&LCChars<'a>) -> ParseRes<'a, V>> Parser for F {
91    type Out = V;
92    fn parse<'b>(&self, i: &LCChars<'b>) -> ParseRes<'b, V> {
93        self(i)
94    }
95}
96
97impl Parser for &'static str {
98    type Out = &'static str;
99    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, &'static str> {
100        crate::reader::do_tag(i, self)
101    }
102    fn expected(&self) -> Expected {
103        Expected::Str(self)
104    }
105}
106
107impl Parser for char {
108    type Out = char;
109    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, char> {
110        let mut i2 = i.clone();
111        match i2.next() {
112            Some(c) if c == *self => Ok((i2, *self, None)),
113            _ => i2.err_rp(self),
114        }
115    }
116    fn expected(&self) -> Expected {
117        Expected::Char(*self)
118    }
119}
120
121#[derive(Clone)]
122pub struct Then<A, B> {
123    a: A,
124    b: B,
125}
126
127impl<A, B> Parser for Then<A, B>
128where
129    A: Parser,
130    B: Parser,
131{
132    type Out = (A::Out, B::Out);
133    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, Self::Out> {
134        let (i, v1, c1) = self.a.parse(i)?;
135        let (i, v2, e) = self.b.parse(&i).map_err(|e| e.join_op(c1))?;
136        Ok((i, (v1, v2), e))
137    }
138    fn expected(&self) -> Expected {
139        Expected::first(self.a.expected(), self.b.expected())
140    }
141}
142
143#[derive(Clone)]
144pub struct ThenIg<A, B> {
145    a: A,
146    b: B,
147}
148
149impl<A, B> Parser for ThenIg<A, B>
150where
151    A: Parser,
152    B: Parser,
153{
154    type Out = A::Out;
155    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, Self::Out> {
156        let (i, v1, c1) = self.a.parse(i)?;
157        let (i, _, ct) = self.b.parse(&i).map_err(|e| e.join_op(c1))?;
158        Ok((i, v1, ct))
159    }
160    fn expected(&self) -> Expected {
161        Expected::first(self.a.expected(), self.b.expected())
162    }
163}
164
165#[derive(Clone)]
166pub struct IgThen<A, B> {
167    a: A,
168    b: B,
169}
170
171impl<A, B> Parser for IgThen<A, B>
172where
173    A: Parser,
174    B: Parser,
175{
176    type Out = B::Out;
177    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, Self::Out> {
178        let (i, _, c1) = self.a.parse(i)?;
179        let (i, v2, ex) = self.b.parse(&i).map_err(|e| e.join_op(c1))?;
180        Ok((i, v2, ex))
181    }
182    fn expected(&self) -> Expected {
183        Expected::first(self.a.expected(), self.b.expected())
184    }
185}
186
187#[derive(Clone)]
188pub struct Or<A, B> {
189    a: A,
190    b: B,
191}
192
193impl<A, B, V> Parser for Or<A, B>
194where
195    A: Parser<Out = V>,
196    B: Parser<Out = V>,
197{
198    type Out = V;
199    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, V> {
200        match self.a.parse(i) {
201            Ok((r, v, e)) => Ok((r, v, e)),
202            Err(e) if e.is_brk => Err(e),
203            Err(e) => match self.b.parse(i) {
204                Ok((r, v, ex)) => Ok((r, v, ex)),
205                Err(e2) if e2.is_brk => Err(e2),
206                Err(e2) => Err(e.longer(e2)),
207            },
208        }
209    }
210    fn expected(&self) -> Expected {
211        self.a.expected().or(self.b.expected())
212    }
213}
214
215#[derive(Clone)]
216pub struct Map<A: Parser, B, F: Fn(A::Out) -> B> {
217    a: A,
218    f: F,
219}
220
221impl<A: Parser<Out = AV>, AV, B, F: Fn(A::Out) -> B> Parser for Map<A, B, F> {
222    type Out = B;
223    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, B> {
224        let (ri, v, ex) = self.a.parse(i)?;
225        Ok((ri, (self.f)(v), ex))
226    }
227    fn expected(&self) -> Expected {
228        self.a.expected()
229    }
230}
231
232#[derive(Clone)]
233pub struct TryMap<A: Parser, B, F: Fn(A::Out) -> Result<B, Expected>> {
234    a: A,
235    f: F,
236}
237
238impl<A: Parser, B, F: Fn(A::Out) -> Result<B, Expected>> Parser for TryMap<A, B, F> {
239    type Out = B;
240    fn parse<'a>(&self, i: &LCChars<'a>) -> ParseRes<'a, B> {
241        let (ri, v, ct) = self.a.parse(i)?;
242        match (self.f)(v) {
243            Ok(v2) => Ok((ri, v2, ct)),
244            Err(e) => ri.err_r(e),
245        }
246    }
247    fn expected(&self) -> Expected {
248        self.a.expected()
249    }
250}
251
252pub struct As<A: Parser, R: Clone> {
253    a: A,
254    r: R,
255}
256impl<A: Parser, R: Clone> Parser for As<A, R> {
257    type Out = R;
258    fn parse<'a>(&self, it: &LCChars<'a>) -> ParseRes<'a, R> {
259        let (ri, _, ct) = self.a.parse(it)?;
260        Ok((ri, self.r.clone(), ct))
261    }
262    fn expected(&self) -> Expected {
263        self.a.expected()
264    }
265}
266
267pub struct MapExp<P: Parser, F: Fn(Expected) -> Expected> {
268    p: P,
269    f: F,
270}
271
272impl<P: Parser, F: Fn(Expected) -> Expected> Parser for MapExp<P, F> {
273    type Out = P::Out;
274    fn parse<'a>(&self, it: &LCChars<'a>) -> ParseRes<'a, P::Out> {
275        match self.p.parse(it) {
276            Err(mut e) => {
277                e.exp = (self.f)(e.exp);
278                Err(e)
279            }
280            Ok(ov) => Ok(ov),
281        }
282    }
283}
284pub struct Break<P: Parser> {
285    p: P,
286}
287
288impl<P: Parser> Parser for Break<P> {
289    type Out = P::Out;
290    fn parse<'a>(&self, it: &LCChars<'a>) -> ParseRes<'a, Self::Out> {
291        match self.p.parse(it) {
292            Err(e) => Err(e.brk()),
293            ov => ov,
294        }
295    }
296}
297#[cfg(test)]
298pub mod test {
299    use super::*;
300    #[test]
301    fn test_strs_can_be_parsers() {
302        let p = "(((".ig_then(crate::common::Int);
303        let n = p.parse_s("(((32").unwrap();
304        assert_eq!(n, 32);
305    }
306}