1use super::{Error, Result, RollbackRecord, RollbackType};
2use crate::range::Bound::*;
3use crate::range::RangeArgument;
4use crate::set::Set;
5use std::fmt::{Debug, Display};
6use std::ops::{Add, BitOr, Mul, Neg, Not, Shr, Sub};
7
8type ParseOutput<O> = (O, usize, Option<Error>);
11
12type Parse<'a, I, O> = dyn Fn(&'a [I], usize) -> Result<ParseOutput<O>> + 'a;
13
14fn merge_errors(name: String, pos: usize, err1: Error, err2: Error) -> Error {
15 match (err1, err2) {
16 (
17 Error::Rollback {
18 rollbacks: rollbacks1,
19 },
20 Error::Rollback {
21 rollbacks: rollbacks2,
22 },
23 ) => Error::Rollback {
24 rollbacks: RollbackRecord {
25 name,
26 position: pos,
27 typ: RollbackType::Fail,
28 inner: None,
29 previous_tracks: vec![rollbacks1, rollbacks2],
30 },
31 },
32 (_, err2) => err2,
41 }
42}
43
44fn merge_continuation_errors(
45 name: String,
46 pos: usize,
47 cont_err1: Option<Error>,
48 cont_err2: Option<Error>,
49) -> Option<Error> {
50 match (cont_err1, cont_err2) {
51 (
52 Some(Error::Rollback {
53 rollbacks: rollbacks1,
54 }),
55 Some(Error::Rollback {
56 rollbacks: rollbacks2,
57 }),
58 ) => Some(Error::Rollback {
59 rollbacks: RollbackRecord {
60 name,
61 position: pos,
62 typ: RollbackType::Stop,
63 inner: None,
64 previous_tracks: vec![rollbacks1, rollbacks2],
65 },
66 }),
67 (
68 Some(Error::Rollback {
69 rollbacks: rollbacks1,
70 }),
71 None,
72 ) => Some(Error::Rollback {
73 rollbacks: RollbackRecord {
74 name,
75 position: pos,
76 typ: RollbackType::Stop,
77 inner: None,
78 previous_tracks: vec![rollbacks1],
79 },
80 }),
81 (_, cont_err2) => cont_err2,
90 }
91}
92
93pub struct Parser<'a, I, O> {
95 method: Box<Parse<'a, I, O>>,
96}
97
98impl<'a, I, O> Parser<'a, I, O> {
99 pub fn new<P>(parse: P) -> Parser<'a, I, O>
101 where
102 P: Fn(&'a [I], usize) -> Result<ParseOutput<O>> + 'a,
103 {
104 Parser {
105 method: Box::new(parse),
106 }
107 }
108
109 pub fn parse(&self, input: &'a [I]) -> Result<O> {
111 self.parse_at(input, 0).map(|(out, _, _)| out)
112 }
113
114 #[inline]
116 pub fn parse_at(&self, input: &'a [I], start: usize) -> Result<ParseOutput<O>> {
117 (self.method)(input, start)
118 }
119
120 pub fn map<U, F>(self, f: F) -> Parser<'a, I, U>
122 where
123 F: Fn(O) -> U + 'a,
124 I: 'a,
125 O: 'a,
126 U: 'a,
127 {
128 Parser::new(move |input: &'a [I], start: usize| {
129 self.parse_at(input, start)
130 .map(|(out, pos, cont_err)| (f(out), pos, cont_err))
131 })
132 }
133
134 pub fn convert<U, E, F>(self, f: F) -> Parser<'a, I, U>
136 where
137 F: Fn(O, &Option<Error>) -> ::std::result::Result<U, E> + 'a,
138 E: Debug,
139 O: 'a,
140 U: 'a,
141 {
142 Parser::new(move |input: &'a [I], start: usize| {
143 self.parse_at(input, start)
144 .and_then(|(res, pos, cont_err)| match f(res, &cont_err) {
145 Ok(out) => Ok((out, pos, cont_err)),
146 Err(err) => Err(Error::Conversion {
147 message: format!("Conversion error: {:?}", err),
148 position: start,
149 }),
150 })
151 })
152 }
153
154 pub fn cache(self) -> Parser<'a, I, O>
156 where
157 O: Clone + 'a,
158 {
159 use std::cell::RefCell;
160 use std::collections::HashMap;
161 let results = RefCell::new(HashMap::new());
162 Parser::new(move |input: &'a [I], start: usize| {
163 let key = (start, format!("{:p}", &self.method));
164 results
165 .borrow_mut()
166 .entry(key)
167 .or_insert_with(|| self.parse_at(input, start))
168 .clone()
169 })
170 }
171
172 pub fn debug_ok<S>(self, id: S) -> Parser<'a, I, O>
173 where
174 O: std::fmt::Debug + 'a,
175 S: AsRef<str> + 'a,
176 {
177 Parser::new(move |input: &'a [I], start: usize| {
178 let result = self.parse_at(input, start);
179 if result.is_ok() {
180 println!("[debug] {} at {}: {:?}", id.as_ref(), start, result);
181 }
182 result
183 })
184 }
185
186 pub fn pos(self) -> Parser<'a, I, usize>
188 where
189 O: 'a,
190 {
191 Parser::new(move |input: &'a [I], start: usize| {
192 self.parse_at(input, start)
193 .map(|(_, pos, cont_err)| (pos, pos, cont_err))
194 })
195 }
196
197 pub fn collect(self) -> Parser<'a, I, &'a [I]>
199 where
200 O: 'a,
201 {
202 Parser::new(move |input: &'a [I], start: usize| {
203 self.parse_at(input, start)
204 .map(|(_, end, cont_err)| (&input[start..end], end, cont_err))
205 })
206 }
207
208 pub fn discard(self) -> Parser<'a, I, ()>
210 where
211 O: 'a,
212 {
213 Parser::new(move |input: &'a [I], start: usize| {
214 self.parse_at(input, start)
215 .map(|(_, end, cont_err)| ((), end, cont_err))
216 })
217 }
218
219 pub fn opt(self) -> Parser<'a, I, Option<O>>
221 where
222 O: 'a,
223 {
224 Parser::new(
225 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
226 Ok((out, pos, cont_err)) => Ok((Some(out), pos, cont_err)),
227 Err(err) => Ok((None, start, Some(err))),
228 },
229 )
230 }
231
232 pub fn repeat<R>(self, range: R) -> Parser<'a, I, Vec<O>>
237 where
238 R: RangeArgument<usize> + Debug + 'a,
239 O: 'a,
240 {
241 Parser::new(move |input: &'a [I], start: usize| {
242 let mut items = vec![];
243 let mut pos = start;
244 let mut cont_err = None;
245 loop {
246 match range.end() {
247 Included(&max_count) => {
248 if items.len() >= max_count {
249 break;
250 }
251 }
252 Excluded(&max_count) => {
253 if items.len() + 1 >= max_count {
254 break;
255 }
256 }
257 Unbounded => (),
258 }
259
260 match self.parse_at(input, pos) {
261 Ok((item, item_pos, item_cont_err)) => {
262 items.push(item);
263 pos = item_pos;
264 cont_err = item_cont_err;
265 }
266 Err(err) => {
267 cont_err = merge_continuation_errors(
268 "<Parser::repeat>".into(),
269 pos,
270 cont_err,
271 Some(err),
272 );
273 break;
274 }
275 }
276 }
277 if let Included(&min_count) = range.start() {
278 if items.len() < min_count {
279 return Err(Error::Mismatch {
280 message: format!(
281 "expect repeat at least {} times, found {} times",
282 min_count,
283 items.len()
284 ),
285 position: start,
286 continuation_error: cont_err.map(Box::new),
287 });
288 }
289 }
290 Ok((items, pos, cont_err))
291 })
292 }
293
294 pub fn name(self, name: &'a str) -> Parser<'a, I, O>
296 where
297 O: 'a,
298 {
299 Parser::new(
300 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
301 res @ Ok(_) => res,
302 Err(err) => match err {
303 Error::Custom { .. } => Err(err),
305 _ => Err(Error::Custom {
306 message: format!("failed to parse {}", name),
307 position: start,
308 inner: Some(Box::new(err)),
309 }),
310 },
311 },
312 )
313 }
314
315 pub fn trace<S>(self, id: S) -> Parser<'a, I, O>
317 where
318 O: 'a,
319 S: AsRef<str> + 'a,
320 {
321 Parser::new(
322 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
323 res @ Ok((_, _, None)) => res,
324 Ok((out, pos, Some(Error::Rollback { rollbacks }))) => Ok((
325 out,
326 pos,
327 Some(Error::Rollback {
328 rollbacks: RollbackRecord {
329 name: id.as_ref().into(),
330 position: pos,
331 typ: RollbackType::Stop,
332 inner: None,
333 previous_tracks: vec![rollbacks],
334 },
335 }),
336 )),
337 Ok((out, pos, Some(cont_err))) => Ok((
338 out,
339 pos,
340 Some(Error::Rollback {
341 rollbacks: RollbackRecord {
342 name: id.as_ref().into(),
343 position: pos,
344 typ: RollbackType::Stop,
345 inner: Some(Box::new(cont_err)),
346 previous_tracks: vec![],
347 },
348 }),
349 )),
350 Err(err) => match err {
351 Error::Rollback { rollbacks } => Err(Error::Rollback {
352 rollbacks: RollbackRecord {
353 name: id.as_ref().into(),
354 position: start,
355 typ: RollbackType::Fail,
356 inner: None,
357 previous_tracks: vec![rollbacks],
358 },
359 }),
360 _ => Err(Error::Rollback {
361 rollbacks: RollbackRecord {
362 name: id.as_ref().into(),
363 position: start,
364 typ: RollbackType::Fail,
365 inner: Some(Box::new(err)),
366 previous_tracks: vec![],
367 },
368 }),
369 },
370 },
371 )
372 }
373
374 pub fn expect(self, name: &'a str) -> Parser<'a, I, O>
376 where
377 O: 'a,
378 {
379 Parser::new(
380 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
381 res @ Ok(_) => res,
382 Err(err) => Err(Error::Expect {
383 message: format!("Expect {}", name),
384 position: start,
385 inner: Box::new(err),
386 }),
387 },
388 )
389 }
390}
391
392pub fn empty<'a, I>() -> Parser<'a, I, ()> {
394 Parser::new(|_: &[I], start: usize| Ok(((), start, None)))
395}
396
397pub fn any<'a, I>() -> Parser<'a, I, I>
399where
400 I: Clone,
401{
402 Parser::new(|input: &[I], start: usize| {
403 if let Some(s) = input.get(start) {
404 Ok((s.clone(), start + 1, None))
405 } else {
406 Err(Error::Mismatch {
407 message: "end of input reached".to_owned(),
408 position: start,
409 continuation_error: None,
410 })
411 }
412 })
413}
414
415pub fn sym<'a, I>(t: I) -> Parser<'a, I, I>
417where
418 I: Clone + PartialEq + Display,
419{
420 Parser::new(move |input: &'a [I], start: usize| {
421 if let Some(s) = input.get(start) {
422 if t == *s {
423 Ok((s.clone(), start + 1, None))
424 } else {
425 Err(Error::Mismatch {
426 message: format!("expect: {}, found: {}", t, s),
427 position: start,
428 continuation_error: None,
429 })
430 }
431 } else {
432 Err(Error::Incomplete)
433 }
434 })
435}
436
437pub fn seq<'a, 'b: 'a, I>(tag: &'b [I]) -> Parser<'a, I, &'a [I]>
439where
440 I: PartialEq + Debug,
441{
442 Parser::new(move |input: &'a [I], start: usize| {
443 let mut index = 0;
444 loop {
445 let pos = start + index;
446 if index == tag.len() {
447 return Ok((tag, pos, None));
448 }
449 if let Some(s) = input.get(pos) {
450 if tag[index] != *s {
451 return Err(Error::Mismatch {
452 message: format!("seq {:?} expect: {:?}, found: {:?}", tag, tag[index], s),
453 position: pos,
454 continuation_error: None,
455 });
456 }
457 } else {
458 return Err(Error::Incomplete);
459 }
460 index += 1;
461 }
462 })
463}
464
465pub fn tag<'a, 'b: 'a>(tag: &'b str) -> Parser<'a, char, &'a str> {
467 Parser::new(move |input: &'a [char], start: usize| {
468 let mut pos = start;
469 for c in tag.chars() {
470 if let Some(&s) = input.get(pos) {
471 if c != s {
472 return Err(Error::Mismatch {
473 message: format!("tag {:?} expect: {:?}, found: {}", tag, c, s),
474 position: pos,
475 continuation_error: None,
476 });
477 }
478 } else {
479 return Err(Error::Incomplete);
480 }
481 pos += 1;
482 }
483 Ok((tag, pos, None))
484 })
485}
486
487pub fn list<'a, I, O, U>(
489 parser: Parser<'a, I, O>,
490 separator: Parser<'a, I, U>,
491) -> Parser<'a, I, Vec<O>>
492where
493 O: 'a,
494 U: 'a,
495{
496 Parser::new(move |input: &'a [I], start: usize| {
497 let mut items = vec![];
498 let mut pos = start;
499 let mut cont_err = None;
500 match parser.parse_at(input, pos) {
501 Ok((first_item, first_pos, _)) => {
502 items.push(first_item);
503 pos = first_pos;
504 loop {
505 match separator.parse_at(input, pos) {
506 Ok((_, sep_pos, _)) => match parser.parse_at(input, sep_pos) {
507 Ok((more_item, more_pos, more_cont_err)) => {
508 items.push(more_item);
509 pos = more_pos;
510 cont_err = more_cont_err;
511 }
512 Err(err) => {
513 cont_err = merge_continuation_errors(
514 "<list>".into(),
515 pos,
516 cont_err,
517 Some(err),
518 );
519 break;
520 }
521 },
522 Err(err) => {
523 cont_err = merge_continuation_errors(
524 "<list>".into(),
525 pos,
526 cont_err,
527 Some(err),
528 );
529 break;
530 }
531 }
532 }
533 }
534 Err(err) => {
535 cont_err = Some(err);
536 }
537 }
538 Ok((items, pos, cont_err))
539 })
540}
541
542pub fn one_of<'a, I, S>(set: &'a S) -> Parser<'a, I, I>
544where
545 I: Clone + PartialEq + Display + Debug,
546 S: Set<I> + ?Sized,
547{
548 Parser::new(move |input: &'a [I], start: usize| {
549 if let Some(s) = input.get(start) {
550 if set.contains(s) {
551 Ok((s.clone(), start + 1, None))
552 } else {
553 Err(Error::Mismatch {
554 message: format!("expect one of: {}, found: {}", set.to_str(), s),
555 position: start,
556 continuation_error: None,
557 })
558 }
559 } else {
560 Err(Error::Incomplete)
561 }
562 })
563}
564
565pub fn none_of<'a, I, S>(set: &'static S) -> Parser<'a, I, I>
567where
568 I: Clone + PartialEq + Display + Debug,
569 S: Set<I> + ?Sized,
570{
571 Parser::new(move |input: &'a [I], start: usize| {
572 if let Some(s) = input.get(start) {
573 if set.contains(s) {
574 Err(Error::Mismatch {
575 message: format!("expect none of: {}, found: {}", set.to_str(), s),
576 position: start,
577 continuation_error: None,
578 })
579 } else {
580 Ok((s.clone(), start + 1, None))
581 }
582 } else {
583 Err(Error::Incomplete)
584 }
585 })
586}
587
588pub fn is_a<'a, I, F>(predicate: F) -> Parser<'a, I, I>
590where
591 I: Clone + PartialEq + Display + Debug,
592 F: Fn(I) -> bool + 'a,
593{
594 Parser::new(move |input: &'a [I], start: usize| {
595 if let Some(s) = input.get(start) {
596 if predicate(s.clone()) {
597 Ok((s.clone(), start + 1, None))
598 } else {
599 Err(Error::Mismatch {
600 message: format!("is_a predicate failed on: {}", s),
601 position: start,
602 continuation_error: None,
603 })
604 }
605 } else {
606 Err(Error::Incomplete)
607 }
608 })
609}
610
611pub fn not_a<'a, I, F>(predicate: F) -> Parser<'a, I, I>
613where
614 I: Clone + PartialEq + Display + Debug,
615 F: Fn(I) -> bool + 'a,
616{
617 Parser::new(move |input: &'a [I], start: usize| {
618 if let Some(s) = input.get(start) {
619 if predicate(s.clone()) {
620 Err(Error::Mismatch {
621 message: format!("not_a predicate failed on: {}", s),
622 position: start,
623 continuation_error: None,
624 })
625 } else {
626 Ok((s.clone(), start + 1, None))
627 }
628 } else {
629 Err(Error::Incomplete)
630 }
631 })
632}
633
634pub fn take<'a, I>(n: usize) -> Parser<'a, I, &'a [I]> {
636 Parser::new(move |input: &'a [I], start: usize| {
637 let pos = start + n;
638 if input.len() >= pos {
639 Ok((&input[start..pos], pos, None))
640 } else {
641 Err(Error::Incomplete)
642 }
643 })
644}
645
646pub fn skip<'a, I>(n: usize) -> Parser<'a, I, ()> {
648 Parser::new(move |input: &'a [I], start: usize| {
649 let pos = start + n;
650 if input.len() >= pos {
651 Ok(((), pos, None))
652 } else {
653 Err(Error::Incomplete)
654 }
655 })
656}
657
658pub fn call<'a, I, O, F>(parser_factory: F) -> Parser<'a, I, O>
660where
661 O: 'a,
662 F: Fn() -> Parser<'a, I, O> + 'a,
663{
664 Parser::new(move |input: &'a [I], start: usize| {
665 let parser = parser_factory();
666 parser.parse_at(input, start)
667 })
668}
669
670pub fn end<'a, I>() -> Parser<'a, I, ()>
672where
673 I: Display,
674{
675 Parser::new(|input: &'a [I], start: usize| {
676 if let Some(s) = input.get(start) {
677 Err(Error::Mismatch {
678 message: format!("expect end of input, found: {}", s),
679 position: start,
680 continuation_error: None,
681 })
682 } else {
683 Ok(((), start, None))
684 }
685 })
686}
687
688impl<'a, I, O: 'a, U: 'a> Add<Parser<'a, I, U>> for Parser<'a, I, O> {
690 type Output = Parser<'a, I, (O, U)>;
691
692 fn add(self, other: Parser<'a, I, U>) -> Self::Output {
693 Parser::new(move |input: &'a [I], start: usize| {
694 self.parse_at(input, start)
695 .and_then(
696 |(out1, pos1, cont_err1)| match other.parse_at(input, pos1) {
697 Ok((out2, pos2, cont_err2)) => {
698 let cont_err = if pos2 == pos1 {
699 merge_continuation_errors(
700 "<Add>".into(),
701 pos2,
702 cont_err1,
703 cont_err2,
704 )
705 } else {
706 cont_err2
707 };
708 Ok(((out1, out2), pos2, cont_err))
709 }
710 Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
711 merge_errors("<Add>".into(), pos1, err1, err2)
712 })),
713 },
714 )
715 })
716 }
717}
718
719impl<'a, I, O: 'a, U: 'a> Sub<Parser<'a, I, U>> for Parser<'a, I, O> {
721 type Output = Parser<'a, I, O>;
722
723 fn sub(self, other: Parser<'a, I, U>) -> Self::Output {
724 Parser::new(move |input: &'a [I], start: usize| {
725 self.parse_at(input, start)
726 .and_then(
727 |(out1, pos1, cont_err1)| match other.parse_at(input, pos1) {
728 Ok((_, pos2, cont_err2)) => {
729 let cont_err = if pos2 == pos1 {
730 merge_continuation_errors(
731 "<Sub>".into(),
732 pos2,
733 cont_err1,
734 cont_err2,
735 )
736 } else {
737 cont_err2
738 };
739 Ok((out1, pos2, cont_err))
740 }
741 Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
742 merge_errors("<Sub>".into(), pos1, err1, err2)
743 })),
744 },
745 )
746 })
747 }
748}
749
750impl<'a, I: 'a, O: 'a, U: 'a> Mul<Parser<'a, I, U>> for Parser<'a, I, O> {
752 type Output = Parser<'a, I, U>;
753
754 fn mul(self, other: Parser<'a, I, U>) -> Self::Output {
755 Parser::new(move |input: &'a [I], start: usize| {
756 self.parse_at(input, start)
757 .and_then(|(_, pos1, cont_err1)| match other.parse_at(input, pos1) {
758 Ok((out2, pos2, cont_err2)) => {
759 let cont_err = if pos2 == pos1 {
760 merge_continuation_errors("<Mul>".into(), pos2, cont_err1, cont_err2)
761 } else {
762 cont_err2
763 };
764 Ok((out2, pos2, cont_err))
765 }
766 Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
767 merge_errors("<Mul>".into(), pos1, err1, err2)
768 })),
769 })
770 })
771 }
772}
773
774impl<'a, I, O: 'a, U: 'a, F: Fn(O) -> Parser<'a, I, U> + 'a> Shr<F> for Parser<'a, I, O> {
776 type Output = Parser<'a, I, U>;
777
778 fn shr(self, other: F) -> Self::Output {
779 Parser::new(move |input: &'a [I], start: usize| {
780 self.parse_at(input, start)
781 .and_then(|(out1, pos1, cont_err1)| {
782 other(out1)
783 .parse_at(input, pos1)
784 .map(|(out2, pos2, cont_err2)| {
785 let cont_err = if pos2 == pos1 {
786 merge_continuation_errors(
787 "<Shr>".into(),
788 pos2,
789 cont_err1,
790 cont_err2,
791 )
792 } else {
793 cont_err2
794 };
795 (out2, pos2, cont_err)
796 })
797 })
798 })
799 }
800}
801
802impl<'a, I, O: 'a> BitOr for Parser<'a, I, O> {
804 type Output = Parser<'a, I, O>;
805
806 fn bitor(self, other: Parser<'a, I, O>) -> Self::Output {
807 Parser::new(
808 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
809 Ok(out) => Ok(out),
810 Err(err) => match err {
811 Error::Expect { .. } => Err(err),
812 _ => match other.parse_at(input, start) {
813 Ok((out, pos, cont_err2)) => {
814 let cont_err = if pos == start {
815 merge_continuation_errors(
816 "<Bitor>".into(),
817 pos,
818 Some(err),
819 cont_err2,
820 )
821 } else {
822 cont_err2
823 };
824 Ok((out, pos, cont_err))
825 }
826 Err(err2) => Err(merge_errors("<Bitor>".into(), start, err, err2)),
827 },
828 },
829 },
830 )
831 }
832}
833
834impl<'a, I, O: 'a> Neg for Parser<'a, I, O> {
836 type Output = Parser<'a, I, bool>;
837
838 fn neg(self) -> Self::Output {
839 Parser::new(move |input: &'a [I], start: usize| {
840 self.parse_at(input, start).map(|_| (true, start, None))
841 })
842 }
843}
844
845impl<'a, I, O: 'a> Not for Parser<'a, I, O> {
847 type Output = Parser<'a, I, bool>;
848
849 fn not(self) -> Self::Output {
850 Parser::new(
851 move |input: &'a [I], start: usize| match self.parse_at(input, start) {
852 Ok(_) => Err(Error::Mismatch {
853 message: "not predicate failed".to_string(),
854 position: start,
855 continuation_error: None,
856 }),
857 Err(_) => Ok((true, start, None)),
858 },
859 )
860 }
861}
862
863#[cfg(test)]
864mod tests {
865 use crate::parser::*;
866 use crate::Error;
867
868 #[test]
869 fn byte_works() {
870 let input = b"abcde";
871 let parser = sym(b'a') + one_of(b"ab") - sym(b'C');
872 let output = parser.parse(input);
873 assert_eq!(
874 output,
875 Err(Error::Mismatch {
876 message: "expect: 67, found: 99".to_string(),
877 position: 2,
878 continuation_error: None,
879 })
880 );
881
882 let parser = sym(b'a') * none_of(b"AB") - sym(b'c') + seq(b"de");
883 let output = parser.parse(input);
884 assert_eq!(output, Ok((b'b', &b"de"[..])));
885 assert_eq!(parser.pos().parse(input), Ok(5));
886
887 let parser = sym(b'e') | sym(b'd').expect("d") | empty().map(|_| b'0');
888 let output = parser.parse(input);
889 assert_eq!(
890 output,
891 Err(Error::Expect {
892 message: "Expect d".to_owned(),
893 position: 0,
894 inner: Box::new(Error::Mismatch {
895 message: "expect: 100, found: 97".to_string(),
896 position: 0,
897 continuation_error: None,
898 })
899 })
900 );
901 }
902
903 #[test]
904 fn char_works() {
905 let input = "abcd".chars().collect::<Vec<char>>();
906 let parser = (tag("ab") + sym('c')) | sym('d').map(|_| ("", '0'));
907 let output = parser.parse(&input);
908 assert_eq!(output, Ok(("ab", 'c')));
909 }
910
911 #[test]
912 fn recursive_parser() {
913 #[derive(Debug, PartialEq)]
914 enum Expr {
915 Empty,
916 Group(Box<Expr>),
917 }
918 fn expr() -> Parser<'static, u8, Expr> {
919 (sym(b'(') + call(expr) - sym(b')')).map(|(_, e)| Expr::Group(Box::new(e)))
920 | empty().map(|_| Expr::Empty)
921 }
922 let input = b"(())";
923 let parser = expr();
924 let output = parser.parse(input);
925 assert_eq!(
926 output,
927 Ok(Expr::Group(Box::new(Expr::Group(Box::new(Expr::Empty)))))
928 );
929 }
930
931 #[test]
932 fn chain_parser() {
933 let input = b"5oooooooo";
934 {
935 let parser = one_of(b"0123456789").map(|c| c - b'0')
936 >> |n| take(n as usize) + sym(b'o').repeat(0..);
937 assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], vec![b'o'; 3])));
938 }
939 {
940 let parser =
941 (skip(1) * take(3)) >> |v: &'static [u8]| take(v.len() + 2).map(move |u| (u, v));
942 assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], &b"ooo"[..])));
943 }
944 {
945 let parser = Parser::new(move |input, start| {
946 (skip(1) * take(3))
947 .parse_at(input, start)
948 .and_then(|(v, pos, _)| {
949 take(v.len() + 2)
950 .parse_at(input, pos)
951 .map(|(u, end, _)| ((u, v), end, None))
952 })
953 });
954 assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], &b"ooo"[..])));
955 }
956 }
957
958 #[test]
959 fn repeat_at_least() {
960 let input = b"xxxooo";
961
962 {
963 let parser = sym(b'x').repeat(1..2);
964 let output = parser.parse(input);
965 assert_eq!(output, Ok(vec![b'x'; 1]))
966 }
967
968 {
969 let parser = sym(b'x').repeat(1..);
970 let output = parser.parse(input);
971 assert_eq!(output, Ok(vec![b'x'; 3]))
972 }
973
974 {
975 let parser = sym(b'x').repeat(0..);
976 let output = parser.parse(input);
977 assert_eq!(output, Ok(vec![b'x'; 3]))
978 }
979
980 {
981 let parser = sym(b'y').repeat(0..);
982 let output = parser.parse(input);
983 assert_eq!(output, Ok(vec![]))
984 }
985
986 {
987 let parser = sym(b'y').repeat(1..);
988 let output = parser.parse(input);
989 assert!(output.is_err());
990 }
991
992 {
993 let parser = sym(b'x').repeat(10..);
994 let output = parser.parse(input);
995 assert!(output.is_err());
996 }
997 }
998
999 #[test]
1000 fn repeat_up_to() {
1001 let input = b"xxxooo";
1002
1003 {
1004 let parser = sym(b'x').repeat(..2);
1005 let output = parser.parse(input);
1006 assert_eq!(output, Ok(vec![b'x'; 1]))
1007 }
1008
1009 {
1010 let parser = sym(b'x').repeat(..4);
1011 let output = parser.parse(input);
1012 assert_eq!(output, Ok(vec![b'x'; 3]))
1013 }
1014
1015 {
1016 let parser = sym(b'x').repeat(..);
1017 let output = parser.parse(input);
1018 assert_eq!(output, Ok(vec![b'x'; 3]))
1019 }
1020
1021 {
1022 let parser = sym(b'x').repeat(..0);
1023 let output = parser.parse(input);
1024 assert_eq!(output, Ok(vec![]))
1025 }
1026
1027 {
1028 let parser = sym(b'x').repeat(..10);
1029 let output = parser.parse(input);
1030 assert_eq!(output, Ok(vec![b'x'; 3]))
1031 }
1032 }
1033
1034 #[test]
1035 fn repeat_exactly() {
1036 let input = b"xxxooo";
1037
1038 {
1039 let parser = sym(b'x').repeat(0);
1040 let output = parser.parse(input);
1041 assert_eq!(output, Ok(vec![]))
1042 }
1043
1044 {
1045 let parser = sym(b'x').repeat(1);
1046 let output = parser.parse(input);
1047 assert_eq!(output, Ok(vec![b'x'; 1]))
1048 }
1049
1050 {
1051 let parser = sym(b'x').repeat(2);
1052 let output = parser.parse(input);
1053 assert_eq!(output, Ok(vec![b'x'; 2]))
1054 }
1055
1056 {
1057 let parser = sym(b'x').repeat(3);
1058 let output = parser.parse(input);
1059 assert_eq!(output, Ok(vec![b'x'; 3]))
1060 }
1061
1062 {
1063 let parser = sym(b'x').repeat(4);
1064 let output = parser.parse(input);
1065 assert!(output.is_err())
1066 }
1067 }
1068}