1use {
4 crate::{
5 error::{FullParsingError, ParsingError, ParsingResult},
6 input::Input,
7 pattern::{IntoPattern, Pattern},
8 tuple::{Tuple, first, map_second, tuple},
9 utils::PathLike,
10 },
11 std::{
12 convert::Infallible,
13 fmt::{Debug, Display},
14 iter::FusedIterator,
15 marker::PhantomData,
16 mem::replace,
17 },
18};
19
20pub trait MappingParser<In, Out, NewOut, Reason = Infallible>:
27 Sized + FnMut(In, Out) -> ParsingResult<In, NewOut, Reason>
28{
29}
30
31impl<In, Out, NewOut, Reason, F> MappingParser<In, Out, NewOut, Reason> for F where
32 F: Sized + FnMut(In, Out) -> ParsingResult<In, NewOut, Reason>
33{
34}
35
36pub trait Parser<In: Input, Out, Reason = Infallible>:
39 Sized + FnMut(In) -> ParsingResult<In, Out, Reason>
40{
41 #[expect(clippy::missing_errors_doc)]
43 fn parse(&mut self, input: In) -> ParsingResult<In, Out, Reason> {
44 self(input)
45 }
46
47 fn filter(mut self, mut f: impl FnMut(&Out) -> bool) -> impl Parser<In, Out, Reason> {
49 move |src| match self(src.clone()) {
50 Ok((rest, res)) if f(&res) => Ok((rest, res)),
51 Ok(_) => Err(ParsingError::new_recoverable(src)),
52 Err(err) => Err(err),
53 }
54 }
55
56 fn filter_fatal(
59 mut self,
60 reason: Reason,
61 mut f: impl FnMut(&Out) -> bool,
62 ) -> impl Parser<In, Out, Reason>
63 where
64 Reason: Clone,
65 {
66 move |src| match self(src.clone()) {
67 Ok((rest, res)) if f(&res) => Ok((rest, res)),
68 Ok(_) => Err(ParsingError::new(src, reason.clone())),
69 Err(err) => Err(err),
70 }
71 }
72
73 fn map_reason<NewReason>(
75 mut self,
76 mut f: impl FnMut(Reason) -> NewReason,
77 ) -> impl Parser<In, Out, NewReason> {
78 move |src| self(src).map_err(|e| e.map_reason(&mut f))
79 }
80
81 fn adapt_reason<NewReason>(mut self) -> impl Parser<In, Out, NewReason>
83 where
84 Infallible: From<Reason>,
85 {
86 move |i| self(i).map_err(ParsingError::adapt_reason)
87 }
88
89 fn map<NewOut>(
96 mut self,
97 mut parser: impl MappingParser<In, Out, NewOut, Reason>,
98 ) -> impl Parser<In, NewOut, Reason> {
99 move |src| self(src).and_then(|(i, o)| parser(i, o))
100 }
101
102 fn map_out<NewOut>(
104 mut self,
105 mut f: impl FnMut(Out) -> NewOut,
106 ) -> impl Parser<In, NewOut, Reason> {
107 move |src| self(src).map(map_second(&mut f))
108 }
109
110 fn map_until<NewOut>(
112 mut self,
113 mut f: impl FnMut(Out) -> Option<NewOut>,
114 ) -> impl Parser<In, NewOut, Reason> {
115 move |mut src| {
116 let end = src.clone().end();
117 loop {
118 let (rest, value) = self(replace(&mut src, end.clone())).map(map_second(&mut f))?;
119 src = rest;
120 let Some(value) = value else {
121 continue;
122 };
123 return Ok((src, value));
124 }
125 }
126 }
127
128 #[cfg(feature = "nightly")]
147 fn call<F>(mut self, mut f: F) -> impl Parser<In, F::Output, Reason>
148 where
149 F: FnMut<Out>,
150 Out: core::marker::Tuple,
151 {
152 move |src| self(src).map(map_second(|x| f.call_mut(x)))
153 }
154
155 fn or(mut self, mut parser: impl Parser<In, Out, Reason>) -> impl Parser<In, Out, Reason> {
162 move |src| {
163 let fallback = src.clone();
164 match self(src) {
165 Ok(res) => Ok(res),
166 Err(err) if err.is_recoverable() => parser(fallback),
167 Err(err) => Err(err),
168 }
169 }
170 }
171
172 fn or_nonempty(
177 mut self,
178 mut parser: impl Parser<In, Out, Reason>,
179 ) -> impl Parser<In, Out, Reason> {
180 move |src| {
181 let fallback = src.clone();
182 match self(src) {
183 Ok(res) => Ok(res),
184 Err(err) if err.is_recoverable() && !err.rest.is_empty() => parser(fallback),
185 Err(err) => Err(err),
186 }
187 }
188 }
189
190 fn or_map_rest(mut self, mut f: impl FnMut(In) -> Out) -> impl Parser<In, Out, Reason> {
195 move |src| {
196 let fallback = src.clone();
197 match self(src) {
198 Ok(res) => Ok(res),
199 Err(err) if err.is_recoverable() && !err.rest.is_empty() => {
200 Ok((fallback.clone().end(), f(fallback)))
201 }
202 Err(err) => Err(err),
203 }
204 }
205 }
206
207 fn or_value(mut self, value: Out) -> impl Parser<In, Out, Reason>
213 where
214 Out: Clone,
215 {
216 move |src| {
217 let fallback = src.clone();
218 match self(src) {
219 Ok(res) => Ok(res),
220 Err(err) if err.is_recoverable() => Ok((fallback, value.clone())),
221 Err(err) => Err(err),
222 }
223 }
224 }
225
226 fn and<Other>(
233 mut self,
234 mut parser: impl Parser<In, Other, Reason>,
235 ) -> impl Parser<In, (Out, Other), Reason> {
236 move |src| {
237 let (rest, out) = self(src.clone())?;
238 match parser(rest) {
239 Ok((rest, new_out)) => Ok((rest, (out, new_out))),
240 Err(mut err) => {
241 if err.is_recoverable() {
242 err.rest = src;
243 }
244 Err(err)
245 }
246 }
247 }
248 }
249
250 fn and_value<Other: Clone>(mut self, value: Other) -> impl Parser<In, (Out, Other), Reason> {
256 move |src| {
257 let (rest, out) = self(src)?;
258 Ok((rest, (out, value.clone())))
259 }
260 }
261
262 fn add<New>(
265 mut self,
266 mut parser: impl Parser<In, New, Reason>,
267 ) -> impl Parser<In, Out::Appended<New>, Reason>
268 where
269 Out: Tuple,
270 {
271 move |src| {
272 let (rest, out) = self(src.clone())?;
273 match parser(rest) {
274 Ok((rest, new_out)) => Ok((rest, out.append(new_out))),
275 Err(mut err) => {
276 if err.is_recoverable() {
277 err.rest = src;
278 }
279 Err(err)
280 }
281 }
282 }
283 }
284
285 fn add_value<Other: Clone>(
288 mut self,
289 value: Other,
290 ) -> impl Parser<In, Out::Appended<Other>, Reason>
291 where
292 Out: Tuple,
293 {
294 move |src| {
295 let (rest, out) = self(src)?;
296 Ok((rest, out.append(value.clone())))
297 }
298 }
299
300 fn then<NewOut>(
303 mut self,
304 mut parser: impl Parser<In, NewOut, Reason>,
305 ) -> impl Parser<In, NewOut, Reason> {
306 move |src| {
307 let rest = self(src.clone())?.0;
308 parser(rest).map_err(|mut err| {
309 if err.is_recoverable() {
310 err.rest = src;
311 }
312 err
313 })
314 }
315 }
316
317 fn skip<Skipped>(
322 mut self,
323 mut parser: impl Parser<In, Skipped, Reason>,
324 ) -> impl Parser<In, Out, Reason> {
325 move |src| {
326 let (rest, out) = self(src.clone())?;
327 match parser(rest) {
328 Ok((rest, _)) => Ok((rest, out)),
329 Err(mut err) => {
330 if err.is_recoverable() {
331 err.rest = src;
332 }
333 Err(err)
334 }
335 }
336 }
337 }
338
339 fn expect<NewReason: Clone>(mut self, expected: NewReason) -> impl Parser<In, Out, NewReason> {
341 move |src| self(src).map_err(|e| e.reason(expected.clone()))
342 }
343
344 fn or_reason(mut self, reason: Reason) -> impl Parser<In, Out, Reason>
347 where
348 Reason: Clone,
349 {
350 move |src| self(src).map_err(|e| e.or_reason(reason.clone()))
351 }
352
353 fn or_reason_if_nonempty(mut self, reason: Reason) -> impl Parser<In, Out, Reason>
357 where
358 Reason: Clone,
359 {
360 move |src| self(src).map_err(|e| e.or_reason_if_nonempty(reason.clone()))
361 }
362
363 fn and_span(self) -> impl Parser<In, (Out, In), Reason> {
369 self.map_out(tuple).add_span()
370 }
371
372 fn add_span(mut self) -> impl Parser<In, Out::Appended<In>, Reason>
375 where
376 Out: Tuple,
377 {
378 move |src| {
379 let (rest, out) = self(src.clone())?;
380 let end = src.len().saturating_sub(rest.len());
381 let consumed = src.before(end);
382 Ok((rest, out.append(consumed)))
383 }
384 }
385
386 fn and_rest(self) -> impl Parser<In, (Out, In), Reason> {
388 self.map_out(tuple).add_rest()
389 }
390
391 fn add_rest(mut self) -> impl Parser<In, Out::Appended<In>, Reason>
394 where
395 Out: Tuple,
396 {
397 move |src| self(src).map(|(rest, out)| (rest.clone(), out.append(rest)))
398 }
399
400 fn maybe(mut self) -> impl Parser<In, Option<Out>, Reason> {
402 move |src| match self(src) {
403 Ok((rest, out)) => Ok((rest, Some(out))),
404 Err(err) if err.is_recoverable() => Ok((err.rest, None)),
405 Err(err) => Err(err),
406 }
407 }
408
409 fn ok(mut self) -> impl Parser<In, bool, Reason> {
411 move |src| match self(src) {
412 Ok((rest, _)) => Ok((rest, true)),
413 Err(err) if err.is_recoverable() => Ok((err.rest, false)),
414 Err(err) => Err(err),
415 }
416 }
417
418 fn repeat(mut self) -> impl Parser<In, (), Reason> {
420 move |mut src| loop {
421 match self(src) {
422 Ok((rest, _)) => src = rest,
423 Err(err) if err.is_recoverable() => return Ok((err.rest, ())),
424 Err(err) => return Err(err),
425 }
426 }
427 }
428
429 fn collect<C: Default + Extend<Out>>(mut self) -> impl Parser<In, C, Reason> {
432 move |mut src| {
433 let mut res = C::default();
434 loop {
435 match self(src) {
436 Ok((rest, new)) => {
437 res.extend([new]);
438 src = rest;
439 }
440 Err(err) if err.is_recoverable() => return Ok((err.rest, res)),
441 Err(err) => return Err(err),
442 }
443 }
444 }
445 }
446
447 fn dbg(mut self, label: impl Display) -> impl Parser<In, Out, Reason>
450 where
451 In: Input,
452 Out: Debug,
453 Reason: Debug,
454 {
455 move |src| match self(src) {
456 Ok((rest, out)) => {
457 let until = rest.char_indices().nth(16).map_or(rest.len(), |x| x.0);
458 let r = &rest[..until].escape_debug();
459 eprintln!("{label}: Ok({out:?}) : {r}...");
460 Ok((rest, out))
461 }
462 Err(err) => {
463 let until = err
464 .rest
465 .char_indices()
466 .nth(16)
467 .map_or(err.rest.len(), |x| x.0);
468 let r = &err.rest[..until].escape_debug();
469 eprintln!("{label}: Err({:?}) : {r}...", err.reason);
470 Err(err)
471 }
472 }
473 }
474
475 fn iter(self, input: In) -> Iter<In, Out, Reason, Self> {
478 Iter {
479 input: Some(input),
480 parser: self,
481 _params: PhantomData,
482 }
483 }
484
485 fn with_full_error<'a>(
490 mut self,
491 path: impl PathLike<'a>,
492 full_src: &'a str,
493 ) -> impl FnOnce(In) -> Result<(In, Out), FullParsingError<'a, Reason>>
494 where
495 In: Input,
496 {
497 move |src| self(src).map_err(|e| e.with_src_loc(path, full_src))
498 }
499}
500
501impl<In, Out, Reason, F> Parser<In, Out, Reason> for F
502where
503 In: Input,
504 F: FnMut(In) -> ParsingResult<In, Out, Reason>,
505{
506}
507
508pub struct Iter<In, Out, Reason, P> {
510 input: Option<In>,
511 parser: P,
512 _params: PhantomData<(Out, Reason)>,
513}
514
515impl<In, Out, Reason, P> Iterator for Iter<In, Out, Reason, P>
516where
517 In: Input,
518 P: Parser<In, Out, Reason>,
519{
520 type Item = Result<Out, ParsingError<In, Reason>>;
521
522 fn next(&mut self) -> Option<Self::Item> {
523 let input = self.input.take()?;
524 match (self.parser)(input) {
525 Ok((rest, res)) => {
526 self.input = Some(rest);
527 Some(Ok(res))
528 }
529 Err(err) if err.is_recoverable() => None,
530 Err(err) => Some(Err(err)),
531 }
532 }
533}
534
535impl<In, Out, Reason, P> FusedIterator for Iter<In, Out, Reason, P>
536where
537 In: Input,
538 P: Parser<In, Out, Reason>,
539{
540}
541
542impl<In, Out, Reason, P> Iter<In, Out, Reason, P>
543where
544 In: Input,
545 P: Parser<In, Out, Reason>,
546{
547 pub const fn remainder(&self) -> Option<&In> {
549 self.input.as_ref()
550 }
551}
552
553pub fn ready<In: Input, T: Clone, Reason>(value: T) -> impl Parser<In, T, Reason> {
557 move |i| Ok((i, value.clone()))
558}
559
560pub fn one<In: Input, Reason>(pat: impl IntoPattern) -> impl Parser<In, In, Reason> {
566 let pat = pat.into_pattern();
567 move |input| {
568 pat.immediate_match(input)
569 .map_err(ParsingError::new_recoverable)
570 }
571}
572
573pub fn many<In: Input, Reason>(pat: impl IntoPattern) -> impl Parser<In, In, Reason> {
580 let pat = pat.into_pattern();
581 move |input| Ok(pat.immediate_matches(input))
582}
583
584pub fn until<In: Input, Reason>(pat: impl IntoPattern) -> impl Parser<In, In, Reason> {
593 let pat = pat.into_pattern();
594 move |input| {
595 let input_len = input.len();
596 Ok({
597 pat.first_match(input)
598 .map_or_else(|input| input.split_at(input_len).rev(), map_second(first))
599 })
600 }
601}
602
603pub fn until_ex<In: Input, Reason>(pat: impl IntoPattern) -> impl Parser<In, In, Reason> {
609 let pat = pat.into_pattern();
610 move |input| {
611 pat.first_match_ex(input)
612 .map(map_second(first))
613 .map_err(ParsingError::new_recoverable)
614 }
615}
616
617pub fn group<In: Input>(open: impl IntoPattern, close: impl Pattern) -> impl Parser<In, In, ()> {
638 let open = open.into_pattern();
639 let close = close.into_pattern();
640 move |input| {
641 let Ok((mut rest, _)) = open.immediate_match(&*input) else {
642 return Err(ParsingError::new_recoverable(input));
643 };
644 let mut nesting = 1;
645 while nesting > 0 {
646 let (after_open, (before_open, open)) =
647 open.first_match_ex(rest).unwrap_or(("", (rest, "")));
648 let (after_close, (before_close, close)) =
649 close.first_match_ex(rest).unwrap_or(("", (rest, "")));
650
651 if [open, close] == ["", ""] {
652 let rest_start = input.len() - rest.len();
654 return Err(ParsingError::new(input.after(rest_start), ()));
655 }
656
657 if before_open.len() < before_close.len() {
658 rest = after_open;
659 nesting += 1;
660 } else {
661 rest = after_close;
662 nesting -= 1;
663 }
664 }
665
666 let res_len = input.len() - rest.len();
667 Ok(input.split_at(res_len).rev())
668 }
669}
670
671pub fn group_ex<In: Input>(
692 open: impl IntoPattern,
693 close: impl IntoPattern,
694) -> impl Parser<In, In, ()> {
695 let open = open.into_pattern();
696 let close = close.into_pattern();
697
698 move |input| {
699 let input = match open.immediate_match(input) {
700 Ok((rest, _)) => rest,
701 Err(input) => return Err(ParsingError::new_recoverable(input)),
702 };
703 let mut rest = &*input;
704 let mut nesting = 1;
705 let mut close_len = 0;
706 while nesting > 0 {
707 let (after_open, (before_open, open)) =
708 open.first_match_ex(rest).unwrap_or(("", (rest, "")));
709 let (after_close, (before_close, close)) =
710 close.first_match_ex(rest).unwrap_or(("", (rest, "")));
711
712 if [open, close] == ["", ""] {
713 let rest_start = input.len() - rest.len();
715 return Err(ParsingError::new(input.after(rest_start), ()));
716 }
717
718 if before_open.len() < before_close.len() {
719 rest = after_open;
720 nesting += 1;
721 } else {
722 rest = after_close;
723 close_len = close.len();
724 nesting -= 1;
725 }
726 }
727
728 let res_len = input.len() - rest.len() - close_len;
729 Ok(input
730 .split_at(res_len)
731 .map_second(|rest| rest.after(close_len))
732 .rev())
733 }
734}