1use super::{create_closure_decorator, Accepted};
2use crate::{
3 action::{Action, Input, Output},
4 combinator::Combinator,
5 digest::Digest,
6 instant::Instant,
7};
8
9create_closure_decorator!(Prepare, "See [`Combinator::prepare`].");
10create_closure_decorator!(Then, "See [`Combinator::then`].");
11create_closure_decorator!(Catch, "See [`Combinator::catch`].");
12create_closure_decorator!(Finally, "See [`Combinator::finally`].");
13
14unsafe impl<T: Action, D: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)> Action
15 for Prepare<T, D>
16{
17 type Text = T::Text;
18 type State = T::State;
19 type Heap = T::Heap;
20 type Value = T::Value;
21
22 #[inline]
23 fn exec(
24 &self,
25 mut input: Input<&Instant<&Self::Text>, &mut Self::State, &mut Self::Heap>,
26 ) -> Option<Output<Self::Value>> {
27 (self.inner)(input.reborrow());
28 self.action.exec(input)
29 }
30}
31
32unsafe impl<
33 T: Action<Text: Digest>,
34 D: Fn(Accepted<&Instant<&T::Text>, &mut T::State, &mut T::Heap, &T::Value>),
35 > Action for Then<T, D>
36{
37 type Text = T::Text;
38 type State = T::State;
39 type Heap = T::Heap;
40 type Value = T::Value;
41
42 #[inline]
43 fn exec(
44 &self,
45 mut input: Input<&Instant<&Self::Text>, &mut Self::State, &mut Self::Heap>,
46 ) -> Option<Output<Self::Value>> {
47 self.action.exec(input.reborrow()).inspect(|output| {
48 (self.inner)(unsafe {
49 Accepted::new_unchecked(input.instant, output.as_ref(), input.state, input.heap)
50 });
51 })
52 }
53}
54
55unsafe impl<T: Action, D: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)> Action
56 for Catch<T, D>
57{
58 type Text = T::Text;
59 type State = T::State;
60 type Heap = T::Heap;
61 type Value = T::Value;
62
63 #[inline]
64 fn exec(
65 &self,
66 mut input: Input<&Instant<&Self::Text>, &mut Self::State, &mut Self::Heap>,
67 ) -> Option<Output<Self::Value>> {
68 let output = self.action.exec(input.reborrow());
69 if output.is_none() {
70 (self.inner)(input);
71 }
72 output
73 }
74}
75
76unsafe impl<T: Action, D: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)> Action
77 for Finally<T, D>
78{
79 type Text = T::Text;
80 type State = T::State;
81 type Heap = T::Heap;
82 type Value = T::Value;
83
84 #[inline]
85 fn exec(
86 &self,
87 mut input: Input<&Instant<&Self::Text>, &mut Self::State, &mut Self::Heap>,
88 ) -> Option<Output<Self::Value>> {
89 let output = self.action.exec(input.reborrow());
90 (self.inner)(input);
91 output
92 }
93}
94
95impl<T> Combinator<T> {
96 #[inline]
107 pub fn prepare<F: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)>(
108 self,
109 modifier: F,
110 ) -> Combinator<Prepare<T, F>>
111 where
112 T: Action,
113 {
114 Combinator::new(Prepare::new(self.action, modifier))
115 }
116
117 #[inline]
128 pub fn then<F: Fn(Accepted<&Instant<&T::Text>, &mut T::State, &mut T::Heap, &T::Value>)>(
129 self,
130 modifier: F,
131 ) -> Combinator<Then<T, F>>
132 where
133 T: Action,
134 {
135 Combinator::new(Then::new(self.action, modifier))
136 }
137
138 #[inline]
149 pub fn catch<F: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)>(
150 self,
151 modifier: F,
152 ) -> Combinator<Catch<T, F>>
153 where
154 T: Action,
155 {
156 Combinator::new(Catch::new(self.action, modifier))
157 }
158
159 #[inline]
171 pub fn finally<F: Fn(Input<&Instant<&T::Text>, &mut T::State, &mut T::Heap>)>(
172 self,
173 modifier: F,
174 ) -> Combinator<Finally<T, F>>
175 where
176 T: Action,
177 {
178 Combinator::new(Finally::new(self.action, modifier))
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185 use crate::{contextual, digest::Digest, instant::Instant};
186 use std::{fmt::Debug, ops::RangeFrom, slice::SliceIndex};
187
188 #[derive(Debug, Default, PartialEq, Eq)]
189 pub struct State {
190 from: i32,
191 to: i32,
192 }
193
194 fn helper<Text: ?Sized + Digest>(
195 action: impl Action<Text = Text, State = State, Heap = (), Value = ()>,
196 input: &Text,
197 state: &mut State,
198 digested: Option<usize>,
199 ) where
200 RangeFrom<usize>: SliceIndex<Text, Output = Text>,
201 {
202 assert_eq!(
203 action
204 .exec(Input {
205 instant: &Instant::new(input),
206 state,
207 heap: &mut ()
208 })
209 .map(|o| o.digested),
210 digested
211 )
212 }
213
214 contextual!(State, ());
215
216 fn accepter(
217 ) -> Combinator<impl Action<Text = str, State = State, Heap = (), Value = ()> + Debug + Copy> {
218 wrap(|input| {
219 input.state.to = input.state.from;
220 input.instant.accept(1)
221 })
222 }
223 fn accepter_bytes(
224 ) -> Combinator<impl Action<Text = [u8], State = State, Heap = (), Value = ()> + Debug + Copy> {
225 bytes::wrap(|input| {
226 input.state.to = input.state.from;
227 input.instant.accept(1)
228 })
229 }
230
231 fn rejecter(
232 ) -> Combinator<impl Action<Text = str, State = State, Heap = (), Value = ()> + Debug + Copy> {
233 wrap(|input| {
234 input.state.to = input.state.from;
235 None
236 })
237 }
238 fn rejecter_bytes(
239 ) -> Combinator<impl Action<Text = [u8], State = State, Heap = (), Value = ()> + Debug + Copy> {
240 bytes::wrap(|input| {
241 input.state.to = input.state.from;
242 None
243 })
244 }
245
246 #[test]
247 fn combinator_prepare() {
248 let mut state = State::default();
250 helper(
251 accepter().prepare(|input| {
252 input.state.from = 1;
253 }),
254 "123",
255 &mut state,
256 Some(1),
257 );
258 assert_eq!(state, State { from: 1, to: 1 });
259 let mut state = State::default();
260 helper(
261 accepter_bytes().prepare(|input| {
262 input.state.from = 1;
263 }),
264 b"123",
265 &mut state,
266 Some(1),
267 );
268 assert_eq!(state, State { from: 1, to: 1 });
269
270 let mut state = State::default();
272 helper(
273 rejecter().prepare(|input| {
274 input.state.from = 1;
275 }),
276 "123",
277 &mut state,
278 None,
279 );
280 assert_eq!(state, State { from: 1, to: 1 });
281 let mut state = State::default();
282 helper(
283 rejecter_bytes().prepare(|input| {
284 input.state.from = 1;
285 }),
286 b"123",
287 &mut state,
288 None,
289 );
290 assert_eq!(state, State { from: 1, to: 1 });
291
292 let _ = format!("{:?}", accepter().prepare(|_| {}));
294 let c = accepter().prepare(|_| {});
296 let _c = c;
297 let _c = c.clone();
298 }
299
300 #[test]
301 fn combinator_then() {
302 let mut state = State::default();
304 helper(
305 accepter().then(|input| {
306 input.state.from = 1;
307 }),
308 "123",
309 &mut state,
310 Some(1),
311 );
312 assert_eq!(state, State { from: 1, to: 0 });
313 let mut state = State::default();
314 helper(
315 accepter_bytes().then(|input| {
316 input.state.from = 1;
317 }),
318 b"123",
319 &mut state,
320 Some(1),
321 );
322 assert_eq!(state, State { from: 1, to: 0 });
323
324 let mut state = State::default();
326 helper(
327 rejecter().then(|input| {
328 input.state.from = 1;
329 }),
330 "123",
331 &mut state,
332 None,
333 );
334 assert_eq!(state, State { from: 0, to: 0 });
335 let mut state = State::default();
336 helper(
337 rejecter_bytes().then(|input| {
338 input.state.from = 1;
339 }),
340 b"123",
341 &mut state,
342 None,
343 );
344 assert_eq!(state, State { from: 0, to: 0 });
345
346 let _ = format!("{:?}", accepter().then(|_| {}));
348 let c = accepter().then(|_| {});
350 let _c = c;
351 let _c = c.clone();
352 }
353
354 #[test]
355 fn combinator_catch() {
356 let mut state = State::default();
358 helper(
359 accepter().catch(|input| {
360 input.state.from = 1;
361 }),
362 "123",
363 &mut state,
364 Some(1),
365 );
366 assert_eq!(state, State { from: 0, to: 0 });
367 let mut state = State::default();
368 helper(
369 accepter_bytes().catch(|input| {
370 input.state.from = 1;
371 }),
372 b"123",
373 &mut state,
374 Some(1),
375 );
376 assert_eq!(state, State { from: 0, to: 0 });
377
378 let mut state = State::default();
380 helper(
381 rejecter().catch(|input| {
382 input.state.from = 1;
383 }),
384 "123",
385 &mut state,
386 None,
387 );
388 assert_eq!(state, State { from: 1, to: 0 });
389 let mut state = State::default();
390 helper(
391 rejecter_bytes().catch(|input| {
392 input.state.from = 1;
393 }),
394 b"123",
395 &mut state,
396 None,
397 );
398 assert_eq!(state, State { from: 1, to: 0 });
399
400 let _ = format!("{:?}", accepter().catch(|_| {}));
402 let c = accepter().catch(|_| {});
404 let _c = c;
405 let _c = c.clone();
406 }
407
408 #[test]
409 fn combinator_finally() {
410 let mut state = State::default();
412 helper(
413 accepter().finally(|input| {
414 input.state.to = 1;
415 }),
416 "123",
417 &mut state,
418 Some(1),
419 );
420 assert_eq!(state, State { from: 0, to: 1 });
421 let mut state = State::default();
422 helper(
423 accepter_bytes().finally(|input| {
424 input.state.to = 1;
425 }),
426 b"123",
427 &mut state,
428 Some(1),
429 );
430 assert_eq!(state, State { from: 0, to: 1 });
431
432 let mut state = State::default();
434 helper(
435 rejecter().finally(|input| {
436 input.state.to = 1;
437 }),
438 "123",
439 &mut state,
440 None,
441 );
442 assert_eq!(state, State { from: 0, to: 1 });
443 let mut state = State::default();
444 helper(
445 rejecter_bytes().finally(|input| {
446 input.state.to = 1;
447 }),
448 b"123",
449 &mut state,
450 None,
451 );
452 assert_eq!(state, State { from: 0, to: 1 });
453
454 let _ = format!("{:?}", accepter().finally(|_| {}));
456 let c = accepter().finally(|_| {});
458 let _c = c;
459 let _c = c.clone();
460 }
461}