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}