1use std::ops::RangeBounds;
2
3use crate::parse::Parser;
4use crate::state::ParserState;
5use crate::utils::extract_bounds;
6
7impl<'a, Output> Parser<'a, Output>
8where
9 Self: 'a,
10 Output: 'a,
11{
12 #[inline]
13 pub fn then<Output2>(self, next: Parser<'a, Output2>) -> Parser<'a, (Output, Output2)>
14 where
15 Output2: 'a,
16 {
17 let with = move |state: &mut ParserState<'a>| {
18 let value1 = self.call(state)?;
19 let value2 = next.call(state)?;
20 Some((value1, value2))
21 };
22 Parser::new(with)
23 }
24
25 #[inline]
27 pub fn or(self, other: Parser<'a, Output>) -> Parser<'a, Output> {
28 let or = move |state: &mut ParserState<'a>| {
29 let checkpoint = state.offset;
30 if let Some(value) = self.call(state) {
31 return Some(value);
32 }
33 state.furthest_offset = state.furthest_offset.max(state.offset);
34 state.offset = checkpoint;
35
36 if let Some(value) = other.call(state) {
37 return Some(value);
38 }
39 state.furthest_offset = state.furthest_offset.max(state.offset);
40 state.offset = checkpoint;
41
42 None
43 };
44 Parser::new(or)
45 }
46
47 #[inline]
48 pub fn or_else(self, f: fn() -> Output) -> Parser<'a, Output> {
49 let or_else = move |state: &mut ParserState<'a>| match self.call(state) {
50 Some(value) => Some(value),
51 None => Some(f()),
52 };
53 Parser::new(or_else)
54 }
55
56 #[inline]
57 pub fn opt(self) -> Parser<'a, Option<Output>> {
58 let opt = move |state: &mut ParserState<'a>| {
59 if let Some(value) = self.call(state) {
60 return Some(Some(value));
61 }
62 Some(None)
63 };
64 Parser::new(opt)
65 }
66
67 #[inline]
72 pub fn not<Output2>(self, next: Parser<'a, Output2>) -> Parser<'a, Output>
73 where
74 Output2: 'a,
75 {
76 let not = move |state: &mut ParserState<'a>| {
77 let value = self.call(state)?;
78 let checkpoint = state.offset;
79 let saved_furthest = state.furthest_offset;
80 if next.call(state).is_none() {
81 state.offset = checkpoint;
82 state.furthest_offset = saved_furthest;
83 return Some(value);
84 }
85 state.offset = checkpoint;
86 state.furthest_offset = saved_furthest;
87 None
88 };
89 Parser::new(not)
90 }
91
92 #[inline]
95 pub fn minus<Output2>(self, excluded: Parser<'a, Output2>) -> Parser<'a, Output>
96 where
97 Output2: 'a,
98 {
99 let minus = move |state: &mut ParserState<'a>| {
100 let checkpoint = state.offset;
101 let saved_furthest = state.furthest_offset;
102 if excluded.call(state).is_some() {
103 state.offset = checkpoint;
104 state.furthest_offset = saved_furthest;
105 return None;
106 }
107 state.offset = checkpoint;
108 state.furthest_offset = saved_furthest;
109 self.call(state)
110 };
111 Parser::new(minus)
112 }
113
114 #[inline]
118 pub fn negate(self) -> Parser<'a, ()> {
119 let negate = move |state: &mut ParserState<'a>| {
120 let checkpoint = state.offset;
121 let saved_furthest = state.furthest_offset;
122 if self.call(state).is_none() {
123 state.offset = checkpoint;
124 state.furthest_offset = saved_furthest;
125 return Some(());
126 }
127 state.offset = checkpoint;
128 state.furthest_offset = saved_furthest;
129 None
130 };
131 Parser::new(negate)
132 }
133
134 #[inline]
135 pub fn map<Output2>(self, f: fn(Output) -> Output2) -> Parser<'a, Output2>
136 where
137 Output2: 'a,
138 {
139 let map = move |state: &mut ParserState<'a>| self.call(state).map(f);
140 Parser::new(map)
141 }
142
143 #[inline]
144 pub fn map_with_state<Output2>(
145 self,
146 f: fn(Output, usize, &mut ParserState<'a>) -> Output2,
147 ) -> Parser<'a, Output2>
148 where
149 Output2: 'a,
150 {
151 let map_with_state = move |state: &mut ParserState<'a>| {
152 let offset = state.offset;
153 let result = self.call(state)?;
154 Some(f(result, offset, state))
155 };
156 Parser::new(map_with_state)
157 }
158
159 #[inline]
160 pub fn skip<Output2>(self, next: Parser<'a, Output2>) -> Parser<'a, Output>
161 where
162 Output2: 'a,
163 {
164 let skip = move |state: &mut ParserState<'a>| {
165 let value = self.call(state)?;
166 next.call(state)?;
167 Some(value)
168 };
169 Parser::new(skip)
170 }
171
172 #[inline]
173 pub fn next<Output2>(self, next: Parser<'a, Output2>) -> Parser<'a, Output2>
174 where
175 Output2: 'a,
176 {
177 let next = move |state: &mut ParserState<'a>| {
178 self.call(state)?;
179 next.call(state)
180 };
181 Parser::new(next)
182 }
183
184 #[inline]
185 pub fn many(self, bounds: impl RangeBounds<usize> + 'a) -> Parser<'a, Vec<Output>> {
186 let (lower_bound, upper_bound) = extract_bounds(bounds);
187
188 let many = move |state: &mut ParserState<'a>| {
189 let est = if lower_bound > 0 { lower_bound.max(16) } else { 32 };
190 let mut values = Vec::with_capacity(est);
191
192 while values.len() < upper_bound {
193 if let Some(value) = self.call(state) {
194 values.push(value);
195 } else {
196 break;
197 }
198 }
199 if values.len() >= lower_bound {
200 Some(values)
201 } else {
202 None
203 }
204 };
205
206 Parser::new(many)
207 }
208
209 #[inline]
210 pub fn wrap<Output2, Output3>(
211 self,
212 left: Parser<'a, Output2>,
213 right: Parser<'a, Output3>,
214 ) -> Parser<'a, Output>
215 where
216 Output2: 'a,
217 Output3: 'a,
218 {
219 let wrap = move |state: &mut ParserState<'a>| {
220 #[cfg(feature = "diagnostics")]
221 let open_offset = state.offset;
222 left.call(state)?;
223 #[cfg(feature = "diagnostics")]
224 let open_end = state.offset;
225 let value = self.call(state)?;
226 if right.call(state).is_some() {
227 Some(value)
228 } else {
229 #[cfg(feature = "diagnostics")]
230 {
231 let delimiter = state.src[open_offset..open_end].to_string();
232 state.add_suggestion(|| crate::state::Suggestion {
233 kind: crate::state::SuggestionKind::UnclosedDelimiter {
234 delimiter: delimiter.clone(),
235 open_offset,
236 },
237 message: format!(
238 "close the delimiter with matching `{}`",
239 match delimiter.as_str() {
240 "{" => "}",
241 "[" => "]",
242 "(" => ")",
243 d => d,
244 }
245 ),
246 });
247 state.add_secondary_span(
248 open_offset,
249 format!("unclosed `{}` opened here", delimiter),
250 );
251 }
252 None
253 }
254 };
255 Parser::new(wrap)
256 }
257
258 #[inline]
259 pub fn trim<Output2>(self, trimmer: Parser<'a, Output2>) -> Parser<'a, Output>
260 where
261 Output2: 'a,
262 {
263 let trim = move |state: &mut ParserState<'a>| {
264 trimmer.call(state)?;
265 let value = self.call(state)?;
266 trimmer.call(state)?;
267 Some(value)
268 };
269 Parser::new(trim)
270 }
271
272 #[inline]
273 pub fn trim_keep<Output2>(
274 self,
275 trimmer: Parser<'a, Output2>,
276 ) -> Parser<'a, (Output2, Output, Output2)>
277 where
278 Output2: 'a,
279 {
280 let trim = move |state: &mut ParserState<'a>| {
281 let trim1 = trimmer.call(state)?;
282 let value = self.call(state)?;
283 let trim2 = trimmer.call(state)?;
284 Some((trim1, value, trim2))
285 };
286 Parser::new(trim)
287 }
288
289 #[inline]
292 pub fn sep_by<Output2>(
293 self,
294 sep: Parser<'a, Output2>,
295 bounds: impl RangeBounds<usize> + 'a,
296 ) -> Parser<'a, Vec<Output>>
297 where
298 Output2: 'a,
299 {
300 let (lower_bound, upper_bound) = extract_bounds(bounds);
301
302 let sep_by = move |state: &mut ParserState<'a>| {
303 let est = if lower_bound > 0 { lower_bound.max(16) } else { 32 };
304 let mut values = Vec::with_capacity(est);
305
306 if let Some(value) = self.call(state) {
308 values.push(value);
309 } else if lower_bound == 0 {
310 return Some(values);
311 } else {
312 return None;
313 }
314
315 while values.len() < upper_bound {
318 let cp = state.offset;
319 if sep.call(state).is_none() {
320 state.offset = cp;
321 break;
322 }
323 if let Some(value) = self.call(state) {
324 values.push(value);
325 } else {
326 state.offset = cp;
329 break;
330 }
331 }
332
333 if values.len() >= lower_bound {
334 Some(values)
335 } else {
336 None
337 }
338 };
339
340 Parser::new(sep_by)
341 }
342
343 #[cfg(feature = "diagnostics")]
351 pub fn recover(self, sync: Parser<'a, ()>, sentinel: Output) -> Parser<'a, Output>
352 where
353 Output: Clone,
354 {
355 use crate::state::{push_diagnostic, pop_last_diagnostic};
356
357 let recover = move |state: &mut ParserState<'a>| {
358 let checkpoint = state.offset;
359 if let Some(value) = self.call(state) {
360 return Some(value);
361 }
362
363 let diag = state.snapshot_diagnostic(checkpoint);
365 push_diagnostic(diag);
366
367 state.offset = checkpoint;
368 if sync.call(state).is_some() {
369 Some(sentinel.clone())
371 } else {
372 pop_last_diagnostic();
374 state.offset = checkpoint;
375 None
376 }
377 };
378 Parser::new(recover)
379 }
380
381 #[cfg(not(feature = "diagnostics"))]
383 pub fn recover(self, _sync: Parser<'a, ()>, _sentinel: Output) -> Parser<'a, Output>
384 where
385 Output: Clone,
386 {
387 self
388 }
389
390 #[inline]
391 pub fn look_ahead<Output2>(self, parser: Parser<'a, Output2>) -> Parser<'a, Output>
392 where
393 Output2: 'a,
394 {
395 let look_ahead = move |state: &mut ParserState<'a>| {
396 let value = self.call(state)?;
397 let offset_after_self = state.offset;
398 let lookahead_result = parser.call(state);
399 state.offset = offset_after_self;
400 lookahead_result?;
401 Some(value)
402 };
403 Parser::new(look_ahead)
404 }
405}
406
407impl<'a, Output2> std::ops::BitOr<Parser<'a, Output2>> for Parser<'a, Output2>
408where
409 Output2: 'a,
410{
411 type Output = Parser<'a, Output2>;
412
413 #[inline]
414 fn bitor(self, other: Parser<'a, Output2>) -> Self::Output {
415 self.or(other)
416 }
417}
418
419impl<'a, Output, Output2> std::ops::Add<Parser<'a, Output2>> for Parser<'a, Output>
420where
421 Output: 'a,
422 Output2: 'a,
423{
424 type Output = Parser<'a, (Output, Output2)>;
425
426 #[inline]
427 fn add(self, other: Parser<'a, Output2>) -> Self::Output {
428 self.then(other)
429 }
430}
431
432#[path = "span_trait.rs"]
433mod span_trait;
434pub use span_trait::*;
435
436#[macro_export]
441macro_rules! seq {
442 ($p1:expr, $p2:expr) => {
443 $crate::Parser::new(move |state| {
444 let v1 = $p1.call(state)?;
445 let v2 = $p2.call(state)?;
446 Some((v1, v2))
447 })
448 };
449 ($p1:expr, $p2:expr, $p3:expr) => {
450 $crate::Parser::new(move |state| {
451 let v1 = $p1.call(state)?;
452 let v2 = $p2.call(state)?;
453 let v3 = $p3.call(state)?;
454 Some((v1, v2, v3))
455 })
456 };
457 ($p1:expr, $p2:expr, $p3:expr, $p4:expr) => {
458 $crate::Parser::new(move |state| {
459 let v1 = $p1.call(state)?;
460 let v2 = $p2.call(state)?;
461 let v3 = $p3.call(state)?;
462 let v4 = $p4.call(state)?;
463 Some((v1, v2, v3, v4))
464 })
465 };
466 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr) => {
467 $crate::Parser::new(move |state| {
468 let v1 = $p1.call(state)?;
469 let v2 = $p2.call(state)?;
470 let v3 = $p3.call(state)?;
471 let v4 = $p4.call(state)?;
472 let v5 = $p5.call(state)?;
473 Some((v1, v2, v3, v4, v5))
474 })
475 };
476 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr) => {
477 $crate::Parser::new(move |state| {
478 let v1 = $p1.call(state)?;
479 let v2 = $p2.call(state)?;
480 let v3 = $p3.call(state)?;
481 let v4 = $p4.call(state)?;
482 let v5 = $p5.call(state)?;
483 let v6 = $p6.call(state)?;
484 Some((v1, v2, v3, v4, v5, v6))
485 })
486 };
487 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr, $p7:expr) => {
488 $crate::Parser::new(move |state| {
489 let v1 = $p1.call(state)?;
490 let v2 = $p2.call(state)?;
491 let v3 = $p3.call(state)?;
492 let v4 = $p4.call(state)?;
493 let v5 = $p5.call(state)?;
494 let v6 = $p6.call(state)?;
495 let v7 = $p7.call(state)?;
496 Some((v1, v2, v3, v4, v5, v6, v7))
497 })
498 };
499 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr, $p7:expr, $p8:expr) => {
500 $crate::Parser::new(move |state| {
501 let v1 = $p1.call(state)?;
502 let v2 = $p2.call(state)?;
503 let v3 = $p3.call(state)?;
504 let v4 = $p4.call(state)?;
505 let v5 = $p5.call(state)?;
506 let v6 = $p6.call(state)?;
507 let v7 = $p7.call(state)?;
508 let v8 = $p8.call(state)?;
509 Some((v1, v2, v3, v4, v5, v6, v7, v8))
510 })
511 };
512}
513
514#[macro_export]
519macro_rules! alt {
520 ($p1:expr, $p2:expr) => {
521 $crate::Parser::new(move |state| {
522 let cp = state.offset;
523 if let Some(v) = $p1.call(state) { return Some(v); }
524 state.furthest_offset = state.furthest_offset.max(state.offset);
525 state.offset = cp;
526 if let Some(v) = $p2.call(state) { return Some(v); }
527 state.furthest_offset = state.furthest_offset.max(state.offset);
528 state.offset = cp;
529 None
530 })
531 };
532 ($p1:expr, $p2:expr, $p3:expr) => {
533 $crate::Parser::new(move |state| {
534 let cp = state.offset;
535 if let Some(v) = $p1.call(state) { return Some(v); }
536 state.furthest_offset = state.furthest_offset.max(state.offset);
537 state.offset = cp;
538 if let Some(v) = $p2.call(state) { return Some(v); }
539 state.furthest_offset = state.furthest_offset.max(state.offset);
540 state.offset = cp;
541 if let Some(v) = $p3.call(state) { return Some(v); }
542 state.furthest_offset = state.furthest_offset.max(state.offset);
543 state.offset = cp;
544 None
545 })
546 };
547 ($p1:expr, $p2:expr, $p3:expr, $p4:expr) => {
548 $crate::Parser::new(move |state| {
549 let cp = state.offset;
550 if let Some(v) = $p1.call(state) { return Some(v); }
551 state.furthest_offset = state.furthest_offset.max(state.offset);
552 state.offset = cp;
553 if let Some(v) = $p2.call(state) { return Some(v); }
554 state.furthest_offset = state.furthest_offset.max(state.offset);
555 state.offset = cp;
556 if let Some(v) = $p3.call(state) { return Some(v); }
557 state.furthest_offset = state.furthest_offset.max(state.offset);
558 state.offset = cp;
559 if let Some(v) = $p4.call(state) { return Some(v); }
560 state.furthest_offset = state.furthest_offset.max(state.offset);
561 state.offset = cp;
562 None
563 })
564 };
565 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr) => {
566 $crate::Parser::new(move |state| {
567 let cp = state.offset;
568 if let Some(v) = $p1.call(state) { return Some(v); }
569 state.furthest_offset = state.furthest_offset.max(state.offset);
570 state.offset = cp;
571 if let Some(v) = $p2.call(state) { return Some(v); }
572 state.furthest_offset = state.furthest_offset.max(state.offset);
573 state.offset = cp;
574 if let Some(v) = $p3.call(state) { return Some(v); }
575 state.furthest_offset = state.furthest_offset.max(state.offset);
576 state.offset = cp;
577 if let Some(v) = $p4.call(state) { return Some(v); }
578 state.furthest_offset = state.furthest_offset.max(state.offset);
579 state.offset = cp;
580 if let Some(v) = $p5.call(state) { return Some(v); }
581 state.furthest_offset = state.furthest_offset.max(state.offset);
582 state.offset = cp;
583 None
584 })
585 };
586 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr) => {
587 $crate::Parser::new(move |state| {
588 let cp = state.offset;
589 if let Some(v) = $p1.call(state) { return Some(v); }
590 state.furthest_offset = state.furthest_offset.max(state.offset);
591 state.offset = cp;
592 if let Some(v) = $p2.call(state) { return Some(v); }
593 state.furthest_offset = state.furthest_offset.max(state.offset);
594 state.offset = cp;
595 if let Some(v) = $p3.call(state) { return Some(v); }
596 state.furthest_offset = state.furthest_offset.max(state.offset);
597 state.offset = cp;
598 if let Some(v) = $p4.call(state) { return Some(v); }
599 state.furthest_offset = state.furthest_offset.max(state.offset);
600 state.offset = cp;
601 if let Some(v) = $p5.call(state) { return Some(v); }
602 state.furthest_offset = state.furthest_offset.max(state.offset);
603 state.offset = cp;
604 if let Some(v) = $p6.call(state) { return Some(v); }
605 state.furthest_offset = state.furthest_offset.max(state.offset);
606 state.offset = cp;
607 None
608 })
609 };
610 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr, $p7:expr) => {
611 $crate::Parser::new(move |state| {
612 let cp = state.offset;
613 if let Some(v) = $p1.call(state) { return Some(v); }
614 state.furthest_offset = state.furthest_offset.max(state.offset);
615 state.offset = cp;
616 if let Some(v) = $p2.call(state) { return Some(v); }
617 state.furthest_offset = state.furthest_offset.max(state.offset);
618 state.offset = cp;
619 if let Some(v) = $p3.call(state) { return Some(v); }
620 state.furthest_offset = state.furthest_offset.max(state.offset);
621 state.offset = cp;
622 if let Some(v) = $p4.call(state) { return Some(v); }
623 state.furthest_offset = state.furthest_offset.max(state.offset);
624 state.offset = cp;
625 if let Some(v) = $p5.call(state) { return Some(v); }
626 state.furthest_offset = state.furthest_offset.max(state.offset);
627 state.offset = cp;
628 if let Some(v) = $p6.call(state) { return Some(v); }
629 state.furthest_offset = state.furthest_offset.max(state.offset);
630 state.offset = cp;
631 if let Some(v) = $p7.call(state) { return Some(v); }
632 state.furthest_offset = state.furthest_offset.max(state.offset);
633 state.offset = cp;
634 None
635 })
636 };
637 ($p1:expr, $p2:expr, $p3:expr, $p4:expr, $p5:expr, $p6:expr, $p7:expr, $p8:expr) => {
638 $crate::Parser::new(move |state| {
639 let cp = state.offset;
640 if let Some(v) = $p1.call(state) { return Some(v); }
641 state.furthest_offset = state.furthest_offset.max(state.offset);
642 state.offset = cp;
643 if let Some(v) = $p2.call(state) { return Some(v); }
644 state.furthest_offset = state.furthest_offset.max(state.offset);
645 state.offset = cp;
646 if let Some(v) = $p3.call(state) { return Some(v); }
647 state.furthest_offset = state.furthest_offset.max(state.offset);
648 state.offset = cp;
649 if let Some(v) = $p4.call(state) { return Some(v); }
650 state.furthest_offset = state.furthest_offset.max(state.offset);
651 state.offset = cp;
652 if let Some(v) = $p5.call(state) { return Some(v); }
653 state.furthest_offset = state.furthest_offset.max(state.offset);
654 state.offset = cp;
655 if let Some(v) = $p6.call(state) { return Some(v); }
656 state.furthest_offset = state.furthest_offset.max(state.offset);
657 state.offset = cp;
658 if let Some(v) = $p7.call(state) { return Some(v); }
659 state.furthest_offset = state.furthest_offset.max(state.offset);
660 state.offset = cp;
661 if let Some(v) = $p8.call(state) { return Some(v); }
662 state.furthest_offset = state.furthest_offset.max(state.offset);
663 state.offset = cp;
664 None
665 })
666 };
667}