bogobble/partial/
charbool.rs

1use super::PosTree;
2use crate::traits::*;
3
4pub struct S(pub &'static str);
5
6impl<'a> Parser<'a> for S {
7    type Out = &'static str;
8    fn parse(&self, it: &PIter<'a>) -> ParseRes<'a, Self::Out> {
9        let mut i2 = it.clone();
10        for c in self.0.chars() {
11            match i2.next() {
12                None => return Ok((i2, self.0, None)),
13                Some(nc) if nc == c => {}
14                _ => return Err(i2.err_s(self.0)),
15            }
16        }
17        Ok((i2, self.0, None))
18    }
19}
20
21pub trait PartCharBool: CharBool + Sized {
22    fn p_until<'a, P: Parser<'a, Out = PosTree<I>>, I: Clone>(
23        self,
24        p: P,
25        i: I,
26    ) -> PCUntil<Self, P, I> {
27        PCUntil { c: self, p, i }
28    }
29}
30
31impl<C: CharBool> PartCharBool for C {}
32
33pub struct PCUntil<C, P, I> {
34    c: C,
35    p: P,
36    i: I,
37}
38
39impl<'a, C: CharBool, P: Parser<'a, Out = PosTree<I>>, I: Clone> Parser<'a> for PCUntil<C, P, I> {
40    type Out = (PosTree<I>, P::Out);
41    fn parse(&self, it: &PIter<'a>) -> ParseRes<'a, Self::Out> {
42        let mut i2 = it.clone();
43        loop {
44            let p_err = match self.p.parse(&i2) {
45                Ok((i3, r2, e_op)) => {
46                    let fin = i3.index();
47                    return Ok((
48                        i3,
49                        (PosTree::new(it.index(), fin, self.i.clone()), r2),
50                        e_op,
51                    ));
52                }
53                Err(e) => e,
54            };
55            match i2.next() {
56                Some(c) if self.c.char_bool(c) => {}
57                Some(_) => return Err(i2.err(self.c.expected())),
58                None => return Err(p_err),
59            }
60        }
61    }
62}