parser_fuck/combinators/
and_then.rs

1use crate::common::cell::*;
2use crate::*;
3use std::marker::PhantomData;
4
5/// Fail if the subparser fail, otherwise calls f with the new Parser and parse the Parser
6#[derive(Debug, PartialEq, Eq, Clone)]
7pub struct AndThen<B: Parser<I>, I: TimeTravel, F> {
8    base: B,
9    f: ExtRefCell<F>,
10    _i: PhantomData<I>,
11}
12impl<B: Parser<I>, I: TimeTravel, U, F> AndThen<B, I, F>
13where
14    U: Parser<I>,
15    F: FnMut(B::Output) -> U,
16{
17    pub fn new(base: B, f: F) -> Self {
18        Self {
19            base,
20            f: ExtRefCell::new(f),
21            _i: PhantomData,
22        }
23    }
24}
25impl<B: Parser<I>, I: TimeTravel, U, F> Parser<I> for AndThen<B, I, F>
26where
27    U: Parser<I>,
28    F: FnMut(B::Output) -> U,
29{
30    type Output = U::Output;
31
32    fn parse(&self, mut input: I) -> Option<Self::Output> {
33        let base = self.base.parse(input.ref_clone())?;
34        let f = unsafe { self.f.get_mut() };
35        let then: U = f(base);
36        input.re_ready();
37        then.parse(input)
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use crate::*;
44
45    #[test]
46    fn test() {
47        let code = "asd123";
48        let span = code.span();
49        let x = substr("asd");
50        let t = x.and_then(|_| substr("123"));
51
52        let r = t.parse(span.ref_clone());
53        println!("{:?}", r);
54        assert_eq!(r, Some(3..6))
55    }
56}