1use crate::{
2 combi::{before, not_followed_by, tuple, Chain},
3 error::{self, MessageFrom},
4 input::{InputOnce, Save},
5 prim::{satisfy_map_once, satisfy_once, state_case_once, state_once},
6};
7
8use super::{
9 error::ParseError,
10 parser::{Args, ParserOnce},
11};
12
13pub struct Cont<'a, 'b, I: InputOnce, O, E: ParseError<I>, C, S>(pub(crate) Option<(O, Args<'a, 'b, I, E, C, S>)>);
14
15impl<'a, 'b, I: InputOnce, E: ParseError<I>, C, S> Args<'a, 'b, I, E, C, S> {
16 #[inline(always)]
17 pub fn to<O>(self, value: O) -> Cont<'a, 'b, I, O, E, C, S> {
18 Cont(Some((value, self)))
19 }
20 #[inline(always)]
21 pub fn done(self) -> Cont<'a, 'b, I, (), E, C, S> {
22 Cont(Some(((), self)))
23 }
24
25 #[inline(always)]
26 pub fn fail<M, O>(self, message: M) -> Cont<'a, 'b, I, O, E, C, S>
27 where
28 E: MessageFrom<M>,
29 {
30 if self.error.add(self.input.position(), self.input.position()) {
31 self.error.set(message)
32 }
33 Cont(None)
34 }
35
36 #[inline(always)]
37 pub fn fail_with_pos<M, O>(self, start: I::Position, end: I::Position, message: M) -> Cont<'a, 'b, I, O, E, C, S>
38 where
39 E: MessageFrom<M>,
40 {
41 if self.error.add(start, end) {
42 self.error.set(message)
43 }
44 Cont(None)
45 }
46
47 #[inline(always)]
48 pub fn state<O>(self, f: impl FnOnce(&mut S) -> O) -> Cont<'a, 'b, I, O, E, C, S> {
49 self.then(state_once(f))
50 }
51 #[inline(always)]
52 pub fn state_case<O>(
53 self, f: impl for<'c, 'd> FnOnce(&'c mut S, Args<'c, 'd, I, E, C, ()>) -> Cont<'c, 'd, I, O, E, C, ()>,
54 ) -> Cont<'a, 'b, I, O, E, C, S> {
55 self.then(state_case_once(f))
56 }
57
58 #[inline(always)]
59 pub fn satisfy(self, f: impl FnOnce(&I::Token) -> bool) -> Cont<'a, 'b, I, I::Token, E, C, S>
60 where
61 E: MessageFrom<error::Unexpected<error::Token<I::Token>>>,
62 {
63 self.then(satisfy_once(f))
64 }
65 #[inline(always)]
66 pub fn satisfy_map<O>(self, f: impl FnOnce(&I::Token) -> Option<O>) -> Cont<'a, 'b, I, O, E, C, S>
67 where
68 E: MessageFrom<error::Unexpected<error::Token<I::Token>>>,
69 {
70 self.then(satisfy_map_once(f))
71 }
72 #[inline(always)]
73 pub fn satisfy_cont<O>(
74 mut self, f: impl FnOnce(&I::Token, Args<'a, 'b, I, E, C, S>) -> Option<Cont<'a, 'b, I, O, E, C, S>>,
75 ) -> Cont<'a, 'b, I, O, E, C, S>
76 where
77 E: MessageFrom<error::Unexpected<error::Token<I::Token>>>,
78 {
79 match self.uncons() {
80 None => Cont(None),
81 Some((c, start)) => {
82 let Args { input, config, state, consume, error } = self;
83 let (input2, error2) = unsafe { (&mut *(input as *mut I), &mut *(error as *mut E)) };
85 match f(&c, Args { input, config, state, consume, error }) {
86 Some(k) => k,
87 None => {
88 let end = input2.position();
89 if error2.add(start, end) {
90 error2.set(error::unexpected(error::token(c)));
91 }
92 Cont(None)
93 },
94 }
95 },
96 }
97 }
98
99 #[inline(always)]
100 pub fn then<P: ParserOnce<I, O, E, C, S>, O>(mut self, p: P) -> Cont<'a, 'b, I, O, E, C, S> {
101 Cont(p.run_once(self.by_ref()).map(move |o| (o, self)))
102 }
103
104 #[inline(always)]
105 pub fn tuple<PS, O>(self, ps: PS) -> Cont<'a, 'b, I, O, E, C, S>
106 where
107 Chain<PS>: ParserOnce<I, O, E, C, S>,
108 {
109 self.then(tuple(ps))
110 }
111
112 #[inline(always)]
113 pub fn before<P: ParserOnce<I, O, E, C, S>, O>(self, p: P) -> Cont<'a, 'b, I, O, E, C, S>
114 where
115 I: Save,
116 S: Save,
117 {
118 self.then(before(p))
119 }
120
121 #[inline(always)]
122 pub fn not_followed_by<P: ParserOnce<I, O, E, C, S>, O, L>(self, p: P, label: L) -> Cont<'a, 'b, I, (), E, C, S>
123 where
124 E: MessageFrom<error::Unexpected<error::Format<L>>>,
125 I: Save,
126 S: Save,
127 {
128 self.then(not_followed_by(p, label))
129 }
130
131 #[inline(always)]
132 pub fn config<O>(self, f: impl FnOnce(&'a C, Self) -> Cont<'a, 'b, I, O, E, C, S>) -> Cont<'a, 'b, I, O, E, C, S> {
133 f(self.config, self)
134 }
135}
136
137impl<'a, 'b, I: InputOnce, O, E: ParseError<I>, C, S> Cont<'a, 'b, I, O, E, C, S> {
138 #[inline(always)]
139 pub fn ignore(self) -> Option<Args<'a, 'b, I, E, C, S>> {
140 self.0.map(|x| x.1)
141 }
142
143 #[inline(always)]
144 pub fn to<O2>(self, value: O2) -> Cont<'a, 'b, I, O2, E, C, S> {
145 self.case(|_, k| k.to(value))
146 }
147 #[inline(always)]
148 pub fn case<T>(
149 self, f: impl FnOnce(O, Args<'a, 'b, I, E, C, S>) -> Cont<'a, 'b, I, T, E, C, S>,
150 ) -> Cont<'a, 'b, I, T, E, C, S> {
151 Cont(self.0.and_then(|(o, k)| f(o, k).0))
152 }
153 #[inline(always)]
154 pub fn bind<F: FnOnce(O) -> P, P: ParserOnce<I, O2, E, C, S>, O2>(self, f: F) -> Cont<'a, 'b, I, O2, E, C, S> {
155 self.case(|o, k| k.then(f(o)))
156 }
157
158 #[inline(always)]
159 pub fn map<T>(self, f: impl FnOnce(O) -> T) -> Cont<'a, 'b, I, T, E, C, S> {
160 Cont(self.0.map(|(o, k)| (f(o), k)))
161 }
162 #[inline(always)]
163 pub fn and<P: ParserOnce<I, O2, E, C, S>, O2>(self, p: P) -> Cont<'a, 'b, I, (O, O2), E, C, S> {
164 self.case(|o1, k| k.then(p).map(|o2| (o1, o2)))
165 }
166 #[inline(always)]
167 pub fn left<P: ParserOnce<I, O2, E, C, S>, O2>(self, p: P) -> Cont<'a, 'b, I, O, E, C, S> {
168 self.case(|o, k| k.then(p).to(o))
169 }
170 #[inline(always)]
171 pub fn right<P: ParserOnce<I, O2, E, C, S>, O2>(self, p: P) -> Cont<'a, 'b, I, O2, E, C, S> {
172 self.case(|_, k| k.then(p))
173 }
174}