1pub trait Point: Ord + Copy {
59 fn zero() -> Self;
61}
62
63impl Point for usize { fn zero() -> usize { 0 } }
64impl Point for i32 { fn zero() -> i32 { 0 } }
65
66pub trait Recoverable {
74 fn recoverable(&self) -> bool;
75}
76
77#[derive(Debug,PartialEq)]
78struct Failures<P, E> {
79 point: P,
80 kinds: Vec<E>,
81}
82
83use std::cmp::Ordering;
84
85impl<P, E> Failures<P, E>
86 where P: Point,
87{
88 fn new() -> Failures<P, E> { Failures { point: P::zero(), kinds: Vec::new() } }
89
90 fn add(&mut self, point: P, failure: E) {
91 match point.cmp(&self.point) {
92 Ordering::Less => {
93 },
95 Ordering::Greater => {
96 self.replace(point, failure);
98 },
99 Ordering::Equal => {
100 self.kinds.push(failure);
103 },
104 }
105 }
106
107 fn replace(&mut self, point: P, failure: E) {
108 self.point = point;
109 self.kinds.clear();
110 self.kinds.push(failure);
111 }
112
113 fn into_progress<T>(self) -> Progress<P, T, Vec<E>> {
114 Progress { point: self.point, status: Status::Failure(self.kinds) }
115 }
116}
117
118#[derive(Debug,PartialEq)]
120pub enum Status<T, E> {
121 Success(T),
122 Failure(E)
123}
124
125impl<T, E> Status<T, E> {
126 fn map<F, T2>(self, f: F) -> Status<T2, E>
127 where F: FnOnce(T) -> T2
128 {
129 match self {
130 Status::Success(x) => Status::Success(f(x)),
131 Status::Failure(x) => Status::Failure(x),
132 }
133 }
134
135 fn map_err<F, E2>(self, f: F) -> Status<T, E2>
136 where F: FnOnce(E) -> E2
137 {
138 match self {
139 Status::Success(x) => Status::Success(x),
140 Status::Failure(x) => Status::Failure(f(x)),
141 }
142 }
143}
144
145#[must_use]
152#[derive(Debug,PartialEq)]
153pub struct Progress<P, T, E> {
154 pub point: P,
156 pub status: Status<T, E>,
158}
159
160impl<P, T, E> Progress<P, T, E> {
161 pub fn success(point: P, val: T) -> Progress<P, T, E> {
162 Progress { point: point, status: Status::Success(val) }
163 }
164
165 pub fn failure(point: P, val: E) -> Progress<P, T, E> {
166 Progress { point: point, status: Status::Failure(val) }
167 }
168
169 pub fn map<F, T2>(self, f: F) -> Progress<P, T2, E>
171 where F: FnOnce(T) -> T2
172 {
173 Progress { point: self.point, status: self.status.map(f) }
174 }
175
176 pub fn map_err<F, E2>(self, f: F) -> Progress<P, T, E2>
178 where F: FnOnce(E) -> E2
179 {
180 Progress { point: self.point, status: self.status.map_err(f) }
181 }
182
183 pub fn optional(self, reset_to: P) -> (P, Option<T>) {
186 match self {
190 Progress { status: Status::Success(val), point } => (point, Some(val)),
191 Progress { status: Status::Failure(..), .. } => (reset_to, None),
192 }
193 }
194}
195
196#[derive(Debug,PartialEq)]
202pub struct ParseMaster<P, E> {
203 failures: Failures<P, E>,
204}
205
206impl<'a, P, E> ParseMaster<P, E>
207 where P: Point,
208 E: Recoverable,
209{
210 pub fn new() -> ParseMaster<P, E> {
211 ParseMaster {
212 failures: Failures::new(),
213 }
214 }
215
216 fn consume<T>(&mut self, progress: Progress<P, T, E>) -> Progress<P, T, ()> {
217 match progress {
218 Progress { status: Status::Success(..), .. } => progress.map_err(|_| ()),
219 Progress { status: Status::Failure(f), point } => {
220 if f.recoverable() {
221 self.failures.add(point, f);
222 } else {
223 self.failures.replace(point, f);
224 }
225 Progress { status: Status::Failure(()), point: point }
226 }
227 }
228 }
229
230 pub fn optional<T, F>(&mut self, point: P, mut parser: F)
234 -> Progress<P, Option<T>, E>
235 where F: FnMut(&mut ParseMaster<P, E>, P) -> Progress<P, T, E>,
236 {
237 let orig_point = point;
238 match parser(self, point) {
242 Progress { status: Status::Success(val), point } => {
243 Progress::success(point, Some(val))
244 },
245 Progress { status: Status::Failure(f), point } => {
246 if f.recoverable() {
247 Progress::success(orig_point, None)
248 } else {
249 Progress::failure(point, f)
250 }
251 },
252 }
253 }
254
255 pub fn alternate<'pm, T>(&'pm mut self) -> Alternate<'pm, P, T, E> {
257 Alternate {
258 master: self,
259 current: None,
260 }
261 }
262
263 pub fn zero_or_more<F, T>(&mut self, point: P, mut parser: F) -> Progress<P, Vec<T>, E>
270 where F: FnMut(&mut ParseMaster<P, E>, P) -> Progress<P, T, E>
271 {
272 let mut current_point = point;
273 let mut values = Vec::new();
274
275 loop {
276 let progress = parser(self, current_point);
277 match progress {
278 Progress { status: Status::Success(v), point } => {
279 values.push(v);
280 current_point = point;
281 },
282 Progress { status: Status::Failure(f), point } => {
283 if f.recoverable() {
284 self.failures.add(point, f);
285 break;
286 } else {
287 return Progress { status: Status::Failure(f), point: point };
288 }
289 },
290 }
291 }
292
293 Progress { status: Status::Success(values), point: current_point }
294 }
295
296 pub fn finish<T>(&mut self, progress: Progress<P, T, E>) -> Progress<P, T, Vec<E>> {
300 let progress = self.consume(progress);
301
302 match progress {
303 Progress { status: Status::Success(..), .. } => progress.map_err(|_| Vec::new()),
304 Progress { status: Status::Failure(..), .. } => {
305 use std::mem;
306 let f = mem::replace(&mut self.failures, Failures::new());
307 f.into_progress()
308 },
309 }
310 }
311}
312
313#[must_use]
315pub struct Alternate<'pm, P : 'pm, T, E : 'pm> {
316 master: &'pm mut ParseMaster<P, E>,
317 current: Option<Progress<P, T, E>>,
318}
319
320impl<'pm, P, T, E> Alternate<'pm, P, T, E>
321 where P: Point,
322 E: Recoverable,
323{
324 fn run_one<F>(&mut self, parser: F)
325 where F: FnOnce(&mut ParseMaster<P, E>) -> Progress<P, T, E>
326 {
327 let r = parser(self.master);
328 if let Some(prev) = self.current.take() {
329 let _ = self.master.consume(prev);
331 }
332 self.current = Some(r);
333 }
334
335 pub fn one<F>(mut self, parser: F) -> Alternate<'pm, P, T, E>
337 where F: FnOnce(&mut ParseMaster<P, E>) -> Progress<P, T, E>
338 {
339 let recoverable =
340 if let Some(Progress { status: Status::Failure(ref f), .. }) = self.current {
341 f.recoverable()
342 } else {
343 false
344 };
345
346 match self.current {
347 None => self.run_one(parser),
348 Some(Progress { status: Status::Success(..), .. }) => {},
349 Some(Progress { status: Status::Failure(..), .. })
350 if recoverable => self.run_one(parser),
351 Some(Progress { status: Status::Failure(..), .. }) => {},
352 }
353
354 self
355 }
356
357 pub fn finish(self) -> Progress<P, T, E> {
359 self.current.unwrap()
360 }
361}
362
363#[macro_export]
365macro_rules! try_parse(
366 ($e:expr) => ({
367 match $e {
368 $crate::Progress { status: $crate::Status::Success(val), point } => (point, val),
369 $crate::Progress { status: $crate::Status::Failure(val), point } => {
370 return $crate::Progress { point: point, status: $crate::Status::Failure(val) }
371 }
372 }
373 });
374);
375
376pub type Identifier<'a, T> = (&'a str, T);
378
379#[derive(Debug,Copy,Clone,PartialEq,Eq)]
384pub struct StringPoint<'a> {
385 pub s: &'a str,
387 pub offset: usize,
389}
390
391impl<'a> PartialOrd for StringPoint<'a> {
392 #[inline]
393 fn partial_cmp(&self, other: &StringPoint<'a>) -> Option<Ordering> {
394 Some(self.cmp(&other))
395 }
396}
397
398impl<'a> Ord for StringPoint<'a> {
399 #[inline]
400 fn cmp(&self, other: &StringPoint<'a>) -> Ordering {
401 self.offset.cmp(&other.offset)
402 }
403}
404
405impl<'a> Point for StringPoint<'a> {
406 fn zero() -> StringPoint<'a> { StringPoint { s: "", offset: 0} }
407}
408
409impl<'a> StringPoint<'a> {
410 #[inline]
411 pub fn new(s: &'a str) -> StringPoint<'a> {
412 StringPoint { s: s, offset: 0 }
413 }
414
415 #[inline]
416 pub fn is_empty(self) -> bool {
417 self.s.is_empty()
418 }
419
420 #[inline]
422 pub fn to(self, other: StringPoint<'a>) -> &'a str {
423 let len = other.offset - self.offset;
424 &self.s[..len]
425 }
426
427 #[inline]
428 fn success(self, len: usize) -> Progress<StringPoint<'a>, &'a str, ()> {
429 let matched = &self.s[..len];
430 let rest = &self.s[len..];
431
432 Progress {
433 point: StringPoint { s: rest, offset: self.offset + len },
434 status: Status::Success(matched)
435 }
436 }
437
438 #[inline]
439 fn fail<T>(self) -> Progress<StringPoint<'a>, T, ()> {
440 Progress { point: self, status: Status::Failure(()) }
441 }
442
443 #[inline]
447 pub fn consume_to(&self, l: Option<usize>) -> Progress<StringPoint<'a>, &'a str, ()> {
448 match l {
449 None => self.fail(),
450 Some(position) => self.success(position),
451 }
452 }
453
454 #[inline]
456 pub fn consume_literal(self, val: &str) -> Progress<StringPoint<'a>, &'a str, ()> {
457 if self.s.starts_with(val) {
458 self.success(val.len())
459 } else {
460 self.fail()
461 }
462 }
463
464 #[inline]
467 pub fn consume_identifier<T>(self, identifiers: &[Identifier<T>])
468 -> Progress<StringPoint<'a>, T, ()>
469 where T: Clone
470 {
471 for &(identifier, ref item) in identifiers {
472 if self.s.starts_with(identifier) {
473 return self
474 .consume_to(Some(identifier.len()))
475 .map(|_| item.clone())
476 .map_err(|_| unreachable!());
477 }
478 }
479
480 self.fail()
481 }
482}
483
484#[cfg(test)]
485mod test {
486 use super::{ParseMaster,Progress,Status,StringPoint,Recoverable};
487
488 #[derive(Debug,Copy,Clone,PartialEq,Eq,PartialOrd,Ord)]
489 struct AnError(u8);
490
491 impl Recoverable for AnError {
492 fn recoverable(&self) -> bool { self.0 < 0x80 }
493 }
494
495 type SimpleMaster = ParseMaster<usize, AnError>;
496 type SimpleProgress<T> = Progress<usize, T, AnError>;
497
498 #[test]
499 fn one_error() {
500 let mut d = ParseMaster::new();
501
502 let r = d.finish::<()>(Progress { point: 0, status: Status::Failure(AnError(1)) });
503
504 assert_eq!(r, Progress { point: 0, status: Status::Failure(vec![AnError(1)]) });
505 }
506
507 #[test]
508 fn two_error_at_same_point() {
509 let mut d = ParseMaster::new();
510
511 let r = d.alternate::<()>()
512 .one(|_| Progress { point: 0, status: Status::Failure(AnError(1)) })
513 .one(|_| Progress { point: 0, status: Status::Failure(AnError(2)) })
514 .finish();
515
516 let r = d.finish(r);
517
518 assert_eq!(r, Progress { point: 0, status: Status::Failure(vec![AnError(1), AnError(2)]) });
519 }
520
521 #[test]
522 fn first_error_is_better() {
523 let mut d = ParseMaster::new();
524
525 let r = d.alternate::<()>()
526 .one(|_| Progress { point: 1, status: Status::Failure(AnError(1)) })
527 .one(|_| Progress { point: 0, status: Status::Failure(AnError(2)) })
528 .finish();
529
530 let r = d.finish(r);
531
532 assert_eq!(r, Progress { point: 1, status: Status::Failure(vec![AnError(1)]) });
533 }
534
535 #[test]
536 fn second_error_is_better() {
537 let mut d = ParseMaster::new();
538
539 let r = d.alternate::<()>()
540 .one(|_| Progress { point: 0, status: Status::Failure(AnError(1)) })
541 .one(|_| Progress { point: 1, status: Status::Failure(AnError(2)) })
542 .finish();
543
544 let r = d.finish(r);
545
546 assert_eq!(r, Progress { point: 1, status: Status::Failure(vec![AnError(2)]) });
547 }
548
549 #[test]
550 fn one_success() {
551 let mut d = ParseMaster::<_, AnError>::new();
552
553 let r = d.finish(Progress { point: 0, status: Status::Success(42) });
554
555 assert_eq!(r, Progress { point: 0, status: Status::Success(42) });
556 }
557
558 #[test]
559 fn success_after_failure() {
560 let mut d = ParseMaster::new();
561
562 let r = d.alternate()
563 .one(|_| Progress { point: 0, status: Status::Failure(AnError(1)) })
564 .one(|_| Progress { point: 0, status: Status::Success(42) })
565 .finish();
566
567 let r = d.finish(r);
568 assert_eq!(r, Progress { point: 0, status: Status::Success(42) });
569 }
570
571 #[test]
572 fn success_before_failure() {
573 let mut d = ParseMaster::<_, AnError>::new();
574
575 let r = d.alternate()
576 .one(|_| Progress { point: 0, status: Status::Success(42) })
577 .one(|_| panic!("Should not even be called"))
578 .finish();
579
580 let r = d.finish(r);
581 assert_eq!(r, Progress { point: 0, status: Status::Success(42) });
582 }
583
584 #[test]
585 fn sequential_success() {
586 fn first(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
587 Progress { point: pt + 1, status: Status::Success(1) }
588 }
589
590 fn second(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
591 Progress { point: pt + 1, status: Status::Success(2) }
592 }
593
594 fn both(d: &mut SimpleMaster, pt: usize) -> SimpleProgress<(u8,u8)> {
595 let (pt, val1) = try_parse!(first(d, pt));
596 let (pt, val2) = try_parse!(second(d, pt));
597 Progress { point: pt, status: Status::Success((val1, val2)) }
598 }
599
600 let mut d = ParseMaster::new();
601 let r = both(&mut d, 0);
602 let r = d.finish(r);
603
604 assert_eq!(r, Progress { point: 2, status: Status::Success((1,2)) });
605 }
606
607 #[test]
608 fn child_parse_succeeds() {
609 fn parent(d: &mut SimpleMaster, pt: usize) -> SimpleProgress<(u8,u8)> {
610 let (pt, val1) = try_parse!(child(d, pt));
611 Progress { point: pt + 1, status: Status::Success((val1, 2)) }
612 }
613
614 fn child(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
615 Progress { point: pt + 1, status: Status::Success(1) }
616 }
617
618 let mut d = ParseMaster::new();
619 let r = parent(&mut d, 0);
620 let r = d.finish(r);
621
622 assert_eq!(r, Progress { point: 2, status: Status::Success((1, 2)) });
623 }
624
625 #[test]
626 fn child_parse_fails_child_step() {
627 fn parent(d: &mut SimpleMaster, pt: usize) -> SimpleProgress<(u8,u8)> {
628 let (pt, val1) = try_parse!(child(d, pt));
629 Progress { point: pt + 1, status: Status::Success((val1, 2)) }
630 }
631
632 fn child(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
633 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
634 }
635
636 let mut d = ParseMaster::new();
637 let r = parent(&mut d, 0);
638 let r = d.finish(r);
639
640 assert_eq!(r, Progress { point: 1, status: Status::Failure(vec![AnError(1)]) });
641 }
642
643 #[test]
644 fn child_parse_fails_parent_step() {
645 fn parent(d: &mut SimpleMaster, pt: usize) -> SimpleProgress<(u8,u8)> {
646 let (pt, _) = try_parse!(child(d, pt));
647 Progress { point: pt + 1, status: Status::Failure(AnError(2)) }
648 }
649
650 fn child(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
651 Progress { point: pt + 1, status: Status::Success(1) }
652 }
653
654 let mut d = ParseMaster::new();
655 let r = parent(&mut d, 0);
656 let r = d.finish(r);
657
658 assert_eq!(r, Progress { point: 2, status: Status::Failure(vec![AnError(2)]) });
659 }
660
661 #[test]
662 fn alternate_with_children_parses() {
663 fn first(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
664 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
665 }
666
667 fn second(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
668 Progress { point: pt + 1, status: Status::Success(1) }
669 }
670
671 fn both(d: &mut SimpleMaster, pt: usize) -> Progress<usize, u8, AnError> {
672 d.alternate()
673 .one(|d| first(d, pt))
674 .one(|d| second(d, pt))
675 .finish()
676 }
677
678 let mut d = ParseMaster::new();
679 let r = both(&mut d, 0);
680 let r = d.finish(r);
681
682 assert_eq!(r, Progress { point: 1, status: Status::Success(1) });
683 }
684
685 #[test]
686 fn alternate_stops_parsing_after_unrecoverable_failure() {
687 let mut d = ParseMaster::new();
688 let r = d.alternate()
689 .one(|_| Progress { point: 0, status: Status::Failure(AnError(255)) })
690 .one(|_| Progress { point: 0, status: Status::Success(()) })
691 .finish();
692 let r = d.finish(r);
693
694 assert_eq!(r, Progress { point: 0, status: Status::Failure(vec![AnError(255)]) });
695 }
696
697 #[test]
698 fn optional_present() {
699 fn optional(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
700 Progress { point: pt + 1, status: Status::Success(1) }
701 }
702
703 let mut d = ParseMaster::new();
704 let (pt, val) = optional(&mut d, 0).optional(0);
705
706 assert_eq!(pt, 1);
707 assert_eq!(val, Some(1));
708 }
709
710 #[test]
711 fn optional_missing() {
712 fn optional(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
713 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
714 }
715
716 let mut d = ParseMaster::new();
717 let (pt, val) = optional(&mut d, 0).optional(0);
718
719 assert_eq!(pt, 0);
720 assert_eq!(val, None);
721 }
722
723 #[test]
724 fn optional_with_recoverable() {
725 fn optional(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
726 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
727 }
728
729 let mut d = ParseMaster::new();
730 let r = d.optional(0, |pm, pt| optional(pm, pt));
731 let r = d.finish(r);
732
733 assert_eq!(r, Progress { point: 0, status: Status::Success(None) });
734 }
735
736 #[test]
737 fn optional_with_unrecoverable() {
738 fn optional(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
739 Progress { point: pt + 1, status: Status::Failure(AnError(255)) }
740 }
741
742 let mut d = ParseMaster::new();
743 let r = d.optional(0, |pm, pt| optional(pm, pt));
744 let r = d.finish(r);
745
746 assert_eq!(r, Progress { point: 1, status: Status::Failure(vec![AnError(255)]) });
747 }
748
749 #[test]
750 fn zero_or_more() {
751 let mut remaining: u8 = 2;
752
753 let mut body = |_: &mut SimpleMaster, pt: usize| -> SimpleProgress<u8> {
754 if remaining > 0 {
755 remaining -= 1;
756 Progress { point: pt + 1, status: Status::Success(remaining) }
757 } else {
758 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
759 }
760 };
761
762 let mut d = ParseMaster::new();
763 let r = d.zero_or_more(0, |d, pt| body(d, pt));
764 let r = d.finish(r);
765
766 assert_eq!(r, Progress { point: 2, status: Status::Success(vec![1, 0]) });
767 }
768
769 #[test]
770 fn zero_or_more_failure_returns_to_beginning_of_line() {
771 fn body(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
772 Progress { point: pt + 1, status: Status::Failure(AnError(1)) }
773 }
774
775 let mut d = ParseMaster::new();
776 let r = d.zero_or_more(0, |d, pt| body(d, pt));
777 let r = d.finish(r);
778
779 assert_eq!(r, Progress { point: 0, status: Status::Success(vec![]) });
780 }
781
782 #[test]
783 fn zero_or_more_fails_on_unrecoverable_failure() {
784 fn body(_: &mut SimpleMaster, pt: usize) -> SimpleProgress<u8> {
785 Progress { point: pt, status: Status::Failure(AnError(255)) }
786 }
787
788 let mut d = ParseMaster::new();
789 let r = d.zero_or_more(0, |d, pt| body(d, pt));
790 let r = d.finish(r);
791
792 assert_eq!(r, Progress { point: 0, status: Status::Failure(vec![AnError(255)]) });
793 }
794
795 type StringMaster<'a> = ParseMaster<StringPoint<'a>, AnError>;
796 type StringProgress<'a, T> = Progress<StringPoint<'a>, T, AnError>;
797
798 #[test]
799 fn string_sequential() {
800 fn all<'a>(pt: StringPoint<'a>) -> StringProgress<'a, (&'a str, &'a str, &'a str)> {
801 let (pt, a) = try_parse!(pt.consume_literal("a").map_err(|_| AnError(1)));
802 let (pt, b) = try_parse!(pt.consume_literal("b").map_err(|_| AnError(2)));
803 let (pt, c) = try_parse!(pt.consume_literal("c").map_err(|_| AnError(3)));
804
805 Progress { point: pt, status: Status::Success((a,b,c)) }
806 }
807
808 let mut d = ParseMaster::new();
809 let pt = StringPoint::new("abc");
810
811 let r = all(pt);
812 let r = d.finish(r);
813
814 assert_eq!(r, Progress { point: StringPoint { s: "", offset: 3 }, status: Status::Success(("a", "b", "c")) });
815 }
816
817 #[test]
818 fn string_alternate() {
819 fn any<'a>(d: &mut StringMaster<'a>, pt: StringPoint<'a>) -> StringProgress<'a, &'a str> {
820 d.alternate()
821 .one(|_| pt.consume_literal("a").map_err(|_| AnError(1)))
822 .one(|_| pt.consume_literal("b").map_err(|_| AnError(2)))
823 .one(|_| pt.consume_literal("c").map_err(|_| AnError(3)))
824 .finish()
825 }
826
827 let mut d = ParseMaster::new();
828 let pt = StringPoint::new("c");
829
830 let r = any(&mut d, pt);
831 let r = d.finish(r);
832
833 assert_eq!(r, Progress { point: StringPoint { s: "", offset: 1 }, status: Status::Success("c") });
834 }
835
836 #[test]
837 fn string_zero_or_more() {
838 fn any<'a>(d: &mut StringMaster<'a>, pt: StringPoint<'a>) -> StringProgress<'a, Vec<&'a str>> {
839 d.zero_or_more(pt, |_, pt| pt.consume_literal("a").map_err(|_| AnError(1)))
840 }
841
842 let mut d = ParseMaster::new();
843 let pt = StringPoint::new("aaa");
844
845 let r = any(&mut d, pt);
846 let r = d.finish(r);
847
848 assert_eq!(r, Progress { point: StringPoint { s: "", offset: 3 }, status: Status::Success(vec!["a", "a", "a"]) });
849 }
850
851 #[test]
852 fn string_to() {
853 let pt1 = StringPoint::new("hello world");
854 let pt2 = StringPoint { offset: pt1.offset + 5, s: &pt1.s[5..] };
855 assert_eq!("hello", pt1.to(pt2));
856 }
857
858 #[test]
859 fn string_consume_literal() {
860 let pt = StringPoint::new("hello world");
861
862 let r = pt.consume_literal("hello");
863 assert_eq!(r, Progress { point: StringPoint { s: " world", offset: 5 },
864 status: Status::Success("hello") });
865
866 let r = pt.consume_literal("goodbye");
867 assert_eq!(r, Progress { point: StringPoint { s: "hello world", offset: 0 },
868 status: Status::Failure(()) });
869 }
870
871 #[test]
872 fn string_consume_identifier() {
873 let pt = StringPoint::new("hello world");
874
875 let r = pt.consume_identifier(&[("goodbye", 1), ("hello", 2)]);
876 assert_eq!(r, Progress { point: StringPoint { s: " world", offset: 5 },
877 status: Status::Success(2) });
878
879 let r = pt.consume_identifier(&[("red", 3), ("blue", 4)]);
880 assert_eq!(r, Progress { point: StringPoint { s: "hello world", offset: 0 },
881 status: Status::Failure(()) });
882 }
883}