1use crate::lib::fmt;
2
3#[cfg(feature = "std")]
4use std::error::Error as StdError;
5
6use crate::{stream::StreamOnce, ErrorOffset};
7
8use self::ParseResult::*;
9
10pub(crate) trait ResultExt<E, T> {
11 fn committed(self) -> ParseResult<E, T>;
12}
13
14impl<E, T> ResultExt<E, T> for Result<E, T> {
15 fn committed(self) -> ParseResult<E, T> {
16 match self {
17 Ok(x) => CommitOk(x),
18 Err(x) => CommitErr(x),
19 }
20 }
21}
22
23#[macro_export]
24#[doc(hidden)]
25macro_rules! ctry {
26 ($result:expr) => {
27 match $result {
28 $crate::error::ParseResult::CommitOk(x) => (x, $crate::error::Commit::Commit(())),
29 $crate::error::ParseResult::PeekOk(x) => (x, $crate::error::Commit::Peek(())),
30 $crate::error::ParseResult::CommitErr(err) => {
31 return $crate::error::ParseResult::CommitErr(err.into())
32 }
33 $crate::error::ParseResult::PeekErr(err) => {
34 return $crate::error::ParseResult::PeekErr(err.into())
35 }
36 }
37 };
38}
39
40pub trait ErrorInfo<'s, T, R> {
45 type Format: fmt::Display;
46
47 #[allow(clippy::wrong_self_convention)]
48 fn into_info(&'s self) -> Info<T, R, Self::Format>;
49}
50
51impl<'s, 'a, T, R, F> ErrorInfo<'s, T, R> for &'a F
52where
53 F: ErrorInfo<'s, T, R>,
54{
55 type Format = F::Format;
56 fn into_info(&'s self) -> Info<T, R, Self::Format> {
57 (**self).into_info()
58 }
59}
60
61#[derive(Clone, Debug)]
62pub enum Info<T, R, F = &'static str> {
63 Token(T),
64 Range(R),
65 Static(&'static str),
66 Format(F),
67}
68
69impl<'s, T, R, F> ErrorInfo<'s, T, R> for Info<T, R, F>
70where
71 T: Clone,
72 R: Clone,
73 F: fmt::Display + 's,
74{
75 type Format = &'s F;
76 fn into_info(&'s self) -> Info<T, R, <Self as ErrorInfo<'_, T, R>>::Format> {
77 match self {
78 Info::Token(b) => Info::Token(b.clone()),
79 Info::Range(b) => Info::Range(b.clone()),
80 Info::Static(b) => Info::Static(*b),
81 Info::Format(b) => Info::Format(b),
82 }
83 }
84}
85
86impl<R, F> From<char> for Info<char, R, F> {
87 fn from(s: char) -> Self {
88 Info::Token(s)
89 }
90}
91
92impl<'s, R> ErrorInfo<'s, char, R> for char {
93 type Format = &'static str;
94 fn into_info(&self) -> Info<char, R, Self::Format> {
95 Info::Token(*self)
96 }
97}
98
99impl<T, R, F> From<&'static str> for Info<T, R, F> {
100 fn from(s: &'static str) -> Self {
101 Info::Static(s)
102 }
103}
104
105impl<'s, T, R> ErrorInfo<'s, T, R> for &'static str {
106 type Format = &'static str;
107 fn into_info(&self) -> Info<T, R, Self::Format> {
108 Info::Static(*self)
109 }
110}
111
112impl<R, F> From<u8> for Info<u8, R, F> {
113 fn from(s: u8) -> Self {
114 Info::Token(s)
115 }
116}
117
118impl<R> ErrorInfo<'_, Self, R> for u8 {
119 type Format = &'static str;
120 fn into_info(&self) -> Info<Self, R, Self::Format> {
121 Info::Token(*self)
122 }
123}
124
125pub struct Token<T>(pub T);
127
128impl<T, R> From<Token<T>> for Info<T, R, &'static str> {
129 fn from(s: Token<T>) -> Self {
130 Info::Token(s.0)
131 }
132}
133
134impl<'s, T, R> ErrorInfo<'s, T, R> for Token<T>
135where
136 T: Clone,
137{
138 type Format = &'static str;
139 fn into_info(&'s self) -> Info<T, R, Self::Format> {
140 Info::Token(self.0.clone())
141 }
142}
143
144pub struct Range<R>(pub R);
146
147impl<T, R> From<Range<R>> for Info<T, R, &'static str> {
148 fn from(s: Range<R>) -> Self {
149 Info::Range(s.0)
150 }
151}
152
153impl<'s, T, R> ErrorInfo<'s, T, R> for Range<R>
154where
155 R: Clone,
156{
157 type Format = &'static str;
158 fn into_info(&'s self) -> Info<T, R, Self::Format> {
159 Info::Range(self.0.clone())
160 }
161}
162
163pub struct Static(&'static str);
166
167impl<T, R, F> From<Static> for Info<T, R, F>
168where
169 F: fmt::Display,
170{
171 fn from(s: Static) -> Self {
172 Info::Static(s.0)
173 }
174}
175
176impl<'s, T, R> ErrorInfo<'s, T, R> for Static {
177 type Format = &'static str;
178 fn into_info(&'s self) -> Info<T, R, Self::Format> {
179 Info::Static(self.0)
180 }
181}
182
183pub struct Format<F>(pub F)
185where
186 F: fmt::Display;
187
188impl<T, R, F> From<Format<F>> for Info<T, R, F>
189where
190 F: fmt::Display,
191{
192 fn from(s: Format<F>) -> Self {
193 Info::Format(s.0)
194 }
195}
196
197impl<'s, T, R, F> ErrorInfo<'s, T, R> for Format<F>
198where
199 F: fmt::Display + 's,
200{
201 type Format = &'s F;
202 fn into_info(&'s self) -> Info<T, R, Self::Format> {
203 Info::Format(&self.0)
204 }
205}
206
207#[derive(Clone, PartialEq, Debug, Copy)]
213pub enum Commit<T> {
214 Commit(T),
217 Peek(T),
220}
221
222impl<T> AsMut<T> for Commit<T> {
223 fn as_mut(&mut self) -> &mut T {
224 match *self {
225 Commit::Peek(ref mut t) | Commit::Commit(ref mut t) => t,
226 }
227 }
228}
229
230impl<T> AsRef<T> for Commit<T> {
231 fn as_ref(&self) -> &T {
232 match *self {
233 Commit::Peek(ref t) | Commit::Commit(ref t) => t,
234 }
235 }
236}
237
238impl<T> Commit<T> {
239 pub fn is_peek(&self) -> bool {
241 match *self {
242 Commit::Peek(_) => true,
243 Commit::Commit(_) => false,
244 }
245 }
246
247 pub fn into_inner(self) -> T {
249 match self {
250 Commit::Peek(x) | Commit::Commit(x) => x,
251 }
252 }
253
254 pub fn into_commit(self) -> Commit<T> {
256 Commit::Commit(self.into_inner())
257 }
258
259 pub fn into_peek(self) -> Commit<T> {
261 Commit::Peek(self.into_inner())
262 }
263
264 pub fn map<F, U>(self, f: F) -> Commit<U>
266 where
267 F: FnOnce(T) -> U,
268 {
269 match self {
270 Commit::Peek(x) => Commit::Peek(f(x)),
271 Commit::Commit(x) => Commit::Commit(f(x)),
272 }
273 }
274
275 pub fn merge(&self, current: Commit<T>) -> Commit<T> {
276 match *self {
277 Commit::Peek(_) => current,
278 Commit::Commit(_) => current.into_commit(),
279 }
280 }
281
282 pub fn combine<F, U, E>(self, f: F) -> StdParseResult2<U, E>
325 where
326 F: FnOnce(T) -> StdParseResult2<U, E>,
327 {
328 match self {
329 Commit::Commit(x) => match f(x) {
330 Ok((v, Commit::Peek(()))) => Ok((v, Commit::Commit(()))),
331 Err(Commit::Peek(err)) => Err(Commit::Commit(err)),
332 y => y,
333 },
334 Commit::Peek(x) => f(x),
335 }
336 }
337 pub fn combine_commit<F, U, E>(self, f: F) -> ParseResult<U, E>
338 where
339 F: FnOnce(T) -> ParseResult<U, E>,
340 {
341 use self::ParseResult::*;
342
343 match self {
344 Commit::Commit(x) => match f(x) {
345 PeekOk(v) => CommitOk(v),
346 PeekErr(err) => CommitErr(err.error),
347 y => y,
348 },
349 Commit::Peek(x) => f(x),
350 }
351 }
352}
353
354pub type StdParseResult<O, Input> =
359 Result<(O, Commit<()>), Commit<Tracked<<Input as StreamOnce>::Error>>>;
360pub type StdParseResult2<O, E> = Result<(O, Commit<()>), Commit<Tracked<E>>>;
361
362pub trait StreamError<Item, Range>: Sized {
367 fn unexpected_token(token: Item) -> Self;
368 fn unexpected_range(token: Range) -> Self;
369 fn unexpected_format<T>(msg: T) -> Self
370 where
371 T: fmt::Display;
372 fn unexpected<E>(info: E) -> Self
373 where
374 E: for<'s> ErrorInfo<'s, Item, Range>,
375 {
376 match info.into_info() {
377 Info::Token(b) => Self::unexpected_token(b),
378 Info::Range(b) => Self::unexpected_range(b),
379 Info::Static(b) => Self::unexpected_static_message(b),
380 Info::Format(b) => Self::unexpected_format(b),
381 }
382 }
383 fn unexpected_static_message(msg: &'static str) -> Self {
384 Self::unexpected_format(msg)
385 }
386
387 fn expected_token(token: Item) -> Self;
388 fn expected_range(token: Range) -> Self;
389 fn expected_format<T>(msg: T) -> Self
390 where
391 T: fmt::Display;
392 fn expected<E>(info: E) -> Self
393 where
394 E: for<'s> ErrorInfo<'s, Item, Range>,
395 {
396 match info.into_info() {
397 Info::Token(b) => Self::expected_token(b),
398 Info::Range(b) => Self::expected_range(b),
399 Info::Static(b) => Self::expected_static_message(b),
400 Info::Format(b) => Self::expected_format(b),
401 }
402 }
403 fn expected_static_message(msg: &'static str) -> Self {
404 Self::expected_format(msg)
405 }
406
407 fn message_token(token: Item) -> Self;
408 fn message_range(token: Range) -> Self;
409 fn message_format<T>(msg: T) -> Self
410 where
411 T: fmt::Display;
412 fn message_static_message(msg: &'static str) -> Self {
413 Self::message_format(msg)
414 }
415 fn message<E>(info: E) -> Self
416 where
417 E: for<'s> ErrorInfo<'s, Item, Range>,
418 {
419 match info.into_info() {
420 Info::Token(b) => Self::message_token(b),
421 Info::Range(b) => Self::message_range(b),
422 Info::Static(b) => Self::message_static_message(b),
423 Info::Format(b) => Self::message_format(b),
424 }
425 }
426
427 #[cfg(feature = "std")]
428 fn other<E>(err: E) -> Self
429 where
430 E: StdError + Send + Sync + 'static,
431 {
432 Self::message_format(err)
433 }
434
435 fn end_of_input() -> Self {
436 Self::unexpected_static_message("end of input")
437 }
438
439 fn is_unexpected_end_of_input(&self) -> bool;
440
441 fn into_other<T>(self) -> T
447 where
448 T: StreamError<Item, Range>;
449}
450
451pub trait ParseError<Item, Range, Position>: Sized + PartialEq {
456 type StreamError: StreamError<Item, Range>;
457
458 fn empty(position: Position) -> Self;
462
463 fn from_error(position: Position, err: Self::StreamError) -> Self {
465 let mut errors = Self::empty(position);
466 errors.add(err);
467 errors
468 }
469
470 fn position(&self) -> Position {
471 unimplemented!()
473 }
474
475 fn set_position(&mut self, position: Position);
477
478 fn merge(self, other: Self) -> Self {
482 other
483 }
484
485 fn add(&mut self, err: Self::StreamError);
490
491 fn add_expected<E>(&mut self, info: E)
492 where
493 E: for<'s> ErrorInfo<'s, Item, Range>,
494 {
495 self.add(Self::StreamError::expected(info))
496 }
497
498 fn add_unexpected<E>(&mut self, info: E)
499 where
500 E: for<'s> ErrorInfo<'s, Item, Range>,
501 {
502 self.add(Self::StreamError::unexpected(info))
503 }
504
505 fn add_message<E>(&mut self, info: E)
506 where
507 E: for<'s> ErrorInfo<'s, Item, Range>,
508 {
509 self.add(Self::StreamError::message(info))
510 }
511
512 fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
514 where
515 F: FnOnce(&mut Tracked<Self>);
516
517 fn clear_expected(&mut self) {}
519
520 fn is_unexpected_end_of_input(&self) -> bool;
521
522 fn into_other<T>(self) -> T
524 where
525 T: ParseError<Item, Range, Position>;
526}
527
528pub trait ParseErrorInto<Item, Range, Position>: Sized {
533 fn into_other_error<T, Item2, Range2, Position2>(self) -> T
534 where
535 T: ParseError<Item2, Range2, Position2>,
536 Item2: From<Item>,
537 Range2: From<Range>,
538 Position2: From<Position>;
539}
540
541pub trait StreamErrorInto<Item, Range>: Sized {
546 fn into_other_error<T, Item2, Range2>(self) -> T
547 where
548 T: StreamError<Item2, Range2>,
549 Item2: From<Item>,
550 Range2: From<Range>;
551}
552
553#[derive(Clone, Copy, Debug, PartialEq)]
554pub enum UnexpectedParse {
555 Eoi,
556 Unexpected,
557}
558
559impl fmt::Display for UnexpectedParse {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 write!(f, "{}", self.as_str())
562 }
563}
564
565#[cfg(feature = "std")]
566impl StdError for UnexpectedParse {
567 fn description(&self) -> &str {
568 self.as_str()
569 }
570}
571
572impl UnexpectedParse {
573 fn as_str(&self) -> &str {
574 use self::UnexpectedParse::*;
575 match *self {
576 Unexpected => "unexpected parse",
577 Eoi => "unexpected end of input",
578 }
579 }
580}
581
582impl<Item, Range> StreamError<Item, Range> for UnexpectedParse {
583 #[inline]
584 fn unexpected_token(_: Item) -> Self {
585 UnexpectedParse::Unexpected
586 }
587 #[inline]
588 fn unexpected_range(_: Range) -> Self {
589 UnexpectedParse::Unexpected
590 }
591 #[inline]
592 fn unexpected_format<T>(_: T) -> Self
593 where
594 T: fmt::Display,
595 {
596 UnexpectedParse::Unexpected
597 }
598
599 #[inline]
600 fn expected_token(_: Item) -> Self {
601 UnexpectedParse::Unexpected
602 }
603 #[inline]
604 fn expected_range(_: Range) -> Self {
605 UnexpectedParse::Unexpected
606 }
607 #[inline]
608 fn expected_format<T>(_: T) -> Self
609 where
610 T: fmt::Display,
611 {
612 UnexpectedParse::Unexpected
613 }
614 #[inline]
615 fn message_format<T>(_: T) -> Self
616 where
617 T: fmt::Display,
618 {
619 UnexpectedParse::Unexpected
620 }
621 #[inline]
622 fn message_token(_: Item) -> Self {
623 UnexpectedParse::Unexpected
624 }
625 #[inline]
626 fn message_range(_: Range) -> Self {
627 UnexpectedParse::Unexpected
628 }
629
630 #[inline]
631 fn end_of_input() -> Self {
632 UnexpectedParse::Eoi
633 }
634
635 #[inline]
636 fn is_unexpected_end_of_input(&self) -> bool {
637 *self == UnexpectedParse::Eoi
638 }
639
640 #[inline]
641 fn into_other<T>(self) -> T
642 where
643 T: StreamError<Item, Range>,
644 {
645 match self {
646 UnexpectedParse::Unexpected => T::unexpected_static_message("parse"),
647 UnexpectedParse::Eoi => T::end_of_input(),
648 }
649 }
650}
651
652impl<Item, Range, Position> ParseError<Item, Range, Position> for UnexpectedParse
653where
654 Position: Default,
655{
656 type StreamError = Self;
657 #[inline]
658 fn empty(_position: Position) -> Self {
659 UnexpectedParse::Unexpected
660 }
661
662 #[inline]
663 fn from_error(_: Position, err: Self::StreamError) -> Self {
664 err
665 }
666
667 fn position(&self) -> Position {
668 Position::default()
669 }
670
671 #[inline]
672 fn set_position(&mut self, _position: Position) {}
673
674 #[inline]
675 fn add(&mut self, err: Self::StreamError) {
676 *self = match (*self, err) {
677 (UnexpectedParse::Eoi, _) => UnexpectedParse::Eoi,
678 (_, err) => err,
679 };
680 }
681
682 #[inline]
683 fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
684 where
685 F: FnOnce(&mut Tracked<Self>),
686 {
687 f(self_);
688 self_.error = info;
689 }
690
691 fn is_unexpected_end_of_input(&self) -> bool {
692 *self == UnexpectedParse::Eoi
693 }
694
695 #[inline]
696 fn into_other<T>(self) -> T
697 where
698 T: ParseError<Item, Range, Position>,
699 {
700 T::from_error(Position::default(), StreamError::into_other(self))
701 }
702}
703
704impl<Item, Range, Position> ParseErrorInto<Item, Range, Position> for UnexpectedParse
705where
706 Position: Default,
707{
708 fn into_other_error<T, Item2, Range2, Position2>(self) -> T
709 where
710 T: ParseError<Item2, Range2, Position2>,
711 Item2: From<Item>,
712 Range2: From<Range>,
713 Position2: From<Position>,
714 {
715 T::from_error(
716 Position::default().into(),
717 StreamErrorInto::<Item, Range>::into_other_error(self),
718 )
719 }
720}
721
722impl<Item, Range> StreamErrorInto<Item, Range> for UnexpectedParse {
723 fn into_other_error<T, Item2, Range2>(self) -> T
724 where
725 T: StreamError<Item2, Range2>,
726 Item2: From<Item>,
727 Range2: From<Range>,
728 {
729 StreamError::into_other(self)
730 }
731}
732
733#[derive(Clone, Copy, Debug, PartialEq)]
734pub enum StringStreamError {
735 UnexpectedParse,
736 Eoi,
737 CharacterBoundary,
738}
739
740pub(crate) const CHAR_BOUNDARY_ERROR_MESSAGE: &str = "unexpected slice on character boundary";
741
742impl fmt::Display for StringStreamError {
743 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
744 write!(f, "{}", self.as_str())
745 }
746}
747
748#[cfg(feature = "std")]
749impl StdError for StringStreamError {
750 fn description(&self) -> &str {
751 self.as_str()
752 }
753}
754
755impl StringStreamError {
756 fn as_str(&self) -> &str {
757 use self::StringStreamError::*;
758 match *self {
759 UnexpectedParse => "unexpected parse",
760 Eoi => "unexpected end of input",
761 CharacterBoundary => CHAR_BOUNDARY_ERROR_MESSAGE,
762 }
763 }
764}
765
766impl<Item, Range> StreamError<Item, Range> for StringStreamError {
767 #[inline]
768 fn unexpected_token(_: Item) -> Self {
769 StringStreamError::UnexpectedParse
770 }
771 #[inline]
772 fn unexpected_range(_: Range) -> Self {
773 StringStreamError::UnexpectedParse
774 }
775 #[inline]
776 fn unexpected_format<T>(_msg: T) -> Self
777 where
778 T: fmt::Display,
779 {
780 StringStreamError::UnexpectedParse
781 }
782
783 #[inline]
784 fn expected_token(_: Item) -> Self {
785 StringStreamError::UnexpectedParse
786 }
787 #[inline]
788 fn expected_range(_: Range) -> Self {
789 StringStreamError::UnexpectedParse
790 }
791 #[inline]
792 fn expected_format<T>(_: T) -> Self
793 where
794 T: fmt::Display,
795 {
796 StringStreamError::UnexpectedParse
797 }
798 #[inline]
799 fn message_format<T>(_: T) -> Self
800 where
801 T: fmt::Display,
802 {
803 StringStreamError::UnexpectedParse
804 }
805 #[inline]
806 fn message_token(_: Item) -> Self {
807 StringStreamError::UnexpectedParse
808 }
809 #[inline]
810 fn message_range(_: Range) -> Self {
811 StringStreamError::UnexpectedParse
812 }
813 fn message_static_message(msg: &'static str) -> Self {
814 if msg == CHAR_BOUNDARY_ERROR_MESSAGE {
815 StringStreamError::CharacterBoundary
816 } else {
817 StringStreamError::UnexpectedParse
818 }
819 }
820 #[inline]
821 fn end_of_input() -> Self {
822 StringStreamError::Eoi
823 }
824 #[inline]
825 fn is_unexpected_end_of_input(&self) -> bool {
826 *self == StringStreamError::Eoi
827 }
828 #[inline]
829 fn into_other<T>(self) -> T
830 where
831 T: StreamError<Item, Range>,
832 {
833 let msg = match self {
834 StringStreamError::CharacterBoundary => CHAR_BOUNDARY_ERROR_MESSAGE,
835 StringStreamError::UnexpectedParse => "parse",
836 StringStreamError::Eoi => return T::end_of_input(),
837 };
838 T::unexpected_static_message(msg)
839 }
840}
841impl<Item, Range, Position> ParseError<Item, Range, Position> for StringStreamError
842where
843 Position: Default,
844{
845 type StreamError = Self;
846 #[inline]
847 fn empty(_position: Position) -> Self {
848 StringStreamError::UnexpectedParse
849 }
850 #[inline]
851 fn from_error(_: Position, err: Self::StreamError) -> Self {
852 err
853 }
854
855 fn position(&self) -> Position {
856 Position::default()
857 }
858
859 #[inline]
860 fn set_position(&mut self, _position: Position) {}
861
862 #[inline]
863 fn add(&mut self, err: Self::StreamError) {
864 *self = match (*self, err) {
865 (StringStreamError::Eoi, _) => StringStreamError::Eoi,
866 (_, err) => err,
867 };
868 }
869
870 #[inline]
871 fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
872 where
873 F: FnOnce(&mut Tracked<Self>),
874 {
875 f(self_);
876 self_.error = info;
877 }
878
879 fn is_unexpected_end_of_input(&self) -> bool {
880 *self == StringStreamError::Eoi
881 }
882
883 #[inline]
884 fn into_other<T>(self) -> T
885 where
886 T: ParseError<Item, Range, Position>,
887 {
888 T::from_error(Position::default(), StreamError::into_other(self))
889 }
890}
891
892impl<Item, Range, Position> ParseErrorInto<Item, Range, Position> for StringStreamError
893where
894 Position: Default,
895{
896 fn into_other_error<T, Item2, Range2, Position2>(self) -> T
897 where
898 T: ParseError<Item2, Range2, Position2>,
899 Item2: From<Item>,
900 Range2: From<Range>,
901 Position2: From<Position>,
902 {
903 T::from_error(
904 Position::default().into(),
905 StreamErrorInto::<Item, Range>::into_other_error(self),
906 )
907 }
908}
909
910impl<Item, Range> StreamErrorInto<Item, Range> for StringStreamError {
911 fn into_other_error<T, Item2, Range2>(self) -> T
912 where
913 T: StreamError<Item2, Range2>,
914 Item2: From<Item>,
915 Range2: From<Range>,
916 {
917 StreamError::into_other(self)
918 }
919}
920
921#[derive(Clone, PartialEq, Debug, Copy)]
925pub struct Tracked<E> {
926 pub error: E,
928 #[doc(hidden)]
929 pub offset: ErrorOffset,
930}
931
932impl<E> From<E> for Tracked<E> {
933 fn from(error: E) -> Self {
934 Tracked {
935 error,
936 offset: ErrorOffset(1),
937 }
938 }
939}
940
941#[derive(Clone, PartialEq, Debug, Copy)]
945pub enum ParseResult<T, E> {
946 CommitOk(T),
949 PeekOk(T),
952 CommitErr(E),
954 PeekErr(Tracked<E>),
956}
957
958impl<T, E> ParseResult<T, E> {
959 #[inline]
960 pub fn is_ok(&self) -> bool {
961 match *self {
962 CommitOk(_) | PeekOk(_) => true,
963 CommitErr(_) | PeekErr(_) => false,
964 }
965 }
966
967 #[inline]
968 pub fn is_err(&self) -> bool {
969 !self.is_ok()
970 }
971
972 pub fn as_ref(&self) -> ParseResult<&T, &E> {
973 match *self {
974 CommitOk(ref t) => CommitOk(t),
975 PeekOk(ref t) => PeekOk(t),
976 CommitErr(ref e) => CommitErr(e),
977 PeekErr(ref e) => PeekErr(Tracked {
978 error: &e.error,
979 offset: e.offset,
980 }),
981 }
982 }
983
984 pub fn and_then<F, T2>(self, f: F) -> F::Output
985 where
986 F: FnOnce(T) -> ParseResult<T2, E>,
987 {
988 match self {
989 CommitOk(t) => match f(t) {
990 CommitOk(t2) | PeekOk(t2) => CommitOk(t2),
991 PeekErr(e) => CommitErr(e.error),
992 CommitErr(e) => CommitErr(e),
993 },
994 PeekOk(t) => f(t),
995 CommitErr(e) => CommitErr(e),
996 PeekErr(e) => PeekErr(e),
997 }
998 }
999
1000 pub fn map_err<F, E2>(self, f: F) -> ParseResult<T, F::Output>
1001 where
1002 F: FnOnce(E) -> E2,
1003 {
1004 match self {
1005 CommitOk(t) => CommitOk(t),
1006 PeekOk(t) => PeekOk(t),
1007 CommitErr(e) => CommitErr(f(e)),
1008 PeekErr(e) => PeekErr(Tracked {
1009 error: f(e.error),
1010 offset: e.offset,
1011 }),
1012 }
1013 }
1014
1015 pub fn map<F, T2>(self, f: F) -> ParseResult<F::Output, E>
1016 where
1017 F: FnOnce(T) -> T2,
1018 {
1019 match self {
1020 CommitOk(t) => CommitOk(f(t)),
1021 PeekOk(t) => PeekOk(f(t)),
1022 CommitErr(e) => CommitErr(e),
1023 PeekErr(e) => PeekErr(e),
1024 }
1025 }
1026}
1027
1028impl<O, E> ParseResult<O, E> {
1029 pub fn into_result(self) -> StdParseResult2<O, E> {
1030 self.into()
1031 }
1032}
1033
1034impl<T, E> Into<Result<Commit<T>, Commit<Tracked<E>>>> for ParseResult<T, E> {
1035 #[inline]
1036 fn into(self) -> Result<Commit<T>, Commit<Tracked<E>>> {
1037 match self {
1038 CommitOk(t) => Ok(Commit::Commit(t)),
1039 PeekOk(t) => Ok(Commit::Peek(t)),
1040 CommitErr(e) => Err(Commit::Commit(e.into())),
1041 PeekErr(e) => Err(Commit::Peek(e)),
1042 }
1043 }
1044}
1045
1046impl<O, E> Into<StdParseResult2<O, E>> for ParseResult<O, E> {
1047 #[inline]
1048 fn into(self) -> StdParseResult2<O, E> {
1049 use self::ParseResult::*;
1050
1051 match self {
1052 CommitOk(t) => Ok((t, Commit::Commit(()))),
1053 PeekOk(t) => Ok((t, Commit::Peek(()))),
1054 CommitErr(e) => Err(Commit::Commit(e.into())),
1055 PeekErr(e) => Err(Commit::Peek(e)),
1056 }
1057 }
1058}
1059
1060impl<O, E> From<StdParseResult2<O, E>> for ParseResult<O, E> {
1061 #[inline]
1062 fn from(result: StdParseResult2<O, E>) -> ParseResult<O, E> {
1063 use self::ParseResult::*;
1064
1065 match result {
1066 Ok((t, Commit::Commit(()))) => CommitOk(t),
1067 Ok((t, Commit::Peek(()))) => PeekOk(t),
1068 Err(Commit::Commit(e)) => CommitErr(e.error),
1069 Err(Commit::Peek(e)) => PeekErr(e),
1070 }
1071 }
1072}
1073
1074#[cfg(all(feature = "std", test))]
1075mod tests_std {
1076
1077 use crate::Parser;
1078
1079 #[derive(Clone, PartialEq, Debug)]
1080 struct CloneOnly {
1081 s: String,
1082 }
1083
1084 #[test]
1085 fn parse_clone_but_not_copy() {
1086 let input = &[
1088 CloneOnly { s: "x".to_string() },
1089 CloneOnly { s: "y".to_string() },
1090 ][..];
1091 let result = crate::parser::range::take_while(|c: CloneOnly| c.s == "x").parse(input);
1092 assert_eq!(
1093 result,
1094 Ok((
1095 &[CloneOnly { s: "x".to_string() }][..],
1096 &[CloneOnly { s: "y".to_string() }][..]
1097 ))
1098 );
1099 }
1100}