combine/stream/
easy.rs

1//! Stream wrapper which provides an informative and easy to use error type.
2//!
3//! Unless you have specific constraints preventing you from using this error type (such as being
4//! a `no_std` environment) you probably want to use this stream type. It can easily be used
5//! through the [`EasyParser::easy_parse`] method.
6//!
7//! The provided `Errors` type is roughly the same as `ParseError` in combine 1.x and 2.x.
8//!
9//! ```
10//! #[macro_use]
11//! extern crate combine;
12//! use combine::{easy, Parser, EasyParser, Stream, many1};
13//! use combine::parser::char::letter;
14//! use combine::stream::StreamErrorFor;
15//! use combine::error::{ParseError, StreamError};
16//!
17//! fn main() {
18//!     parser!{
19//!        fn parser[Input]()(Input) -> String
20//!         where [
21//!             Input: Stream<Token = char, Error = easy::ParseError<Input>>,
22//!             Input::Range: PartialEq,
23//!             // If we want to use the error type explicitly we need to help rustc infer
24//!             // `StreamError` to `easy::Error` (rust-lang/rust#24159)
25//!             Input::Error: ParseError<
26//!                 Input::Token,
27//!                 Input::Range,
28//!                 Input::Position,
29//!                 StreamError = easy::Error<Input::Token, Input::Range>
30//!             >
31//!         ]
32//!         {
33//!             many1(letter()).and_then(|word: String| {
34//!                 if word == "combine" {
35//!                     Ok(word)
36//!                 } else {
37//!                     Err(easy::Error::Expected(easy::Info::Static("combine")))
38//!                 }
39//!             })
40//!         }
41//!     }
42//!
43//!     parser!{
44//!        fn parser2[Input]()(Input) -> String
45//!         where [
46//!             Input: Stream<Token = char>,
47//!         ]
48//!         {
49//!             many1(letter()).and_then(|word: String| {
50//!                 if word == "combine" {
51//!                     Ok(word)
52//!                 } else {
53//!                     // Alternatively it is possible to only use the methods provided by the
54//!                     // `StreamError` trait.
55//!                     // In that case the extra bound is not necessary (and this method will work
56//!                     // for other errors than `easy::Errors`)
57//!                     Err(StreamErrorFor::<Input>::expected_static_message("combine"))
58//!                 }
59//!             })
60//!         }
61//!     }
62//!
63//!     let input = "combin";
64//!     let expected_error = Err(easy::Errors {
65//!         errors: vec![
66//!             easy::Error::Expected("combine".into())
67//!         ],
68//!         position: 0,
69//!     });
70//!     assert_eq!(
71//!         parser().easy_parse(input).map_err(|err| err.map_position(|p| p.translate_position(input))),
72//!         expected_error
73//!     );
74//!     assert_eq!(
75//!         parser2().easy_parse(input).map_err(|err| err.map_position(|p| p.translate_position(input))),
76//!         expected_error
77//!     );
78//! }
79//!
80//! ```
81//!
82//! [`EasyParser::easy_parse`]: super::super::parser::EasyParser::easy_parse
83use std::{error::Error as StdError, fmt};
84
85use crate::error::{Info as PrimitiveInfo, ParseResult, StreamError, Tracked};
86
87use crate::stream::{
88    Positioned, RangeStream, RangeStreamOnce, ResetStream, StreamErrorFor, StreamOnce,
89};
90
91/// Enum holding error information. Variants are defined for `Stream::Token` and `Stream::Range` as
92/// well as string variants holding easy descriptions.
93///
94/// As there is implementations of `From` for `String` and `&'static str` the
95/// constructor need not be used directly as calling `msg.into()` should turn a message into the
96/// correct `Info` variant.
97#[derive(Clone, Debug)]
98pub enum Info<T, R> {
99    Token(T),
100    Range(R),
101    Owned(String),
102    Static(&'static str),
103}
104
105impl<T, R, F> From<PrimitiveInfo<T, R, F>> for Info<T, R>
106where
107    F: fmt::Display,
108{
109    fn from(info: PrimitiveInfo<T, R, F>) -> Self {
110        match info {
111            PrimitiveInfo::Token(b) => Info::Token(b),
112            PrimitiveInfo::Range(b) => Info::Range(b),
113            PrimitiveInfo::Static(b) => Info::Static(b),
114            PrimitiveInfo::Format(b) => Info::Owned(b.to_string()),
115        }
116    }
117}
118
119impl<T, R> Info<T, R> {
120    pub fn map_token<F, U>(self, f: F) -> Info<U, R>
121    where
122        F: FnOnce(T) -> U,
123    {
124        use self::Info::*;
125
126        match self {
127            Token(t) => Token(f(t)),
128            Range(r) => Range(r),
129            Owned(s) => Owned(s),
130            Static(x) => Static(x),
131        }
132    }
133
134    pub fn map_range<F, S>(self, f: F) -> Info<T, S>
135    where
136        F: FnOnce(R) -> S,
137    {
138        use self::Info::*;
139
140        match self {
141            Token(t) => Token(t),
142            Range(r) => Range(f(r)),
143            Owned(s) => Owned(s),
144            Static(x) => Static(x),
145        }
146    }
147}
148
149impl<T: PartialEq, R: PartialEq> PartialEq for Info<T, R> {
150    fn eq(&self, other: &Info<T, R>) -> bool {
151        match (self, other) {
152            (&Info::Token(ref l), &Info::Token(ref r)) => l == r,
153            (&Info::Range(ref l), &Info::Range(ref r)) => l == r,
154            (&Info::Owned(ref l), &Info::Owned(ref r)) => l == r,
155            (&Info::Static(l), &Info::Owned(ref r)) => l == r,
156            (&Info::Owned(ref l), &Info::Static(r)) => l == r,
157            (&Info::Static(l), &Info::Static(r)) => l == r,
158            _ => false,
159        }
160    }
161}
162impl<T: fmt::Display, R: fmt::Display> fmt::Display for Info<T, R> {
163    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164        match *self {
165            Info::Token(ref c) => write!(f, "`{}`", c),
166            Info::Range(ref c) => write!(f, "`{}`", c),
167            Info::Owned(ref s) => write!(f, "{}", s),
168            Info::Static(s) => write!(f, "{}", s),
169        }
170    }
171}
172
173impl<R> From<char> for Info<char, R> {
174    fn from(s: char) -> Info<char, R> {
175        Info::Token(s)
176    }
177}
178impl<T, R> From<String> for Info<T, R> {
179    fn from(s: String) -> Info<T, R> {
180        Info::Owned(s)
181    }
182}
183
184impl<T, R> From<&'static str> for Info<T, R> {
185    fn from(s: &'static str) -> Info<T, R> {
186        Info::Static(s)
187    }
188}
189
190impl<R> From<u8> for Info<u8, R> {
191    fn from(s: u8) -> Info<u8, R> {
192        Info::Token(s)
193    }
194}
195
196/// Enum used to store information about an error that has occurred during parsing.
197#[derive(Debug)]
198pub enum Error<T, R> {
199    /// Error indicating an unexpected token has been encountered in the stream
200    Unexpected(Info<T, R>),
201    /// Error indicating that the parser expected something else
202    Expected(Info<T, R>),
203    /// Generic message
204    Message(Info<T, R>),
205    /// Variant for containing other types of errors
206    Other(Box<dyn StdError + Send + Sync>),
207}
208
209impl<Item, Range> StreamError<Item, Range> for Error<Item, Range>
210where
211    Item: PartialEq,
212    Range: PartialEq,
213{
214    #[inline]
215    fn unexpected_token(token: Item) -> Self {
216        Error::Unexpected(Info::Token(token))
217    }
218    #[inline]
219    fn unexpected_range(token: Range) -> Self {
220        Error::Unexpected(Info::Range(token))
221    }
222    #[inline]
223    fn unexpected_format<T>(msg: T) -> Self
224    where
225        T: fmt::Display,
226    {
227        Error::Unexpected(Info::Owned(msg.to_string()))
228    }
229    #[inline]
230    fn unexpected_static_message(msg: &'static str) -> Self {
231        Error::Unexpected(Info::Static(msg))
232    }
233
234    #[inline]
235    fn expected_token(token: Item) -> Self {
236        Error::Expected(Info::Token(token))
237    }
238    #[inline]
239    fn expected_range(token: Range) -> Self {
240        Error::Expected(Info::Range(token))
241    }
242    #[inline]
243    fn expected_format<T>(msg: T) -> Self
244    where
245        T: fmt::Display,
246    {
247        Error::Expected(Info::Owned(msg.to_string()))
248    }
249    #[inline]
250    fn expected_static_message(msg: &'static str) -> Self {
251        Error::Expected(Info::Static(msg))
252    }
253
254    #[inline]
255    fn message_format<T>(msg: T) -> Self
256    where
257        T: fmt::Display,
258    {
259        Error::Message(Info::Owned(msg.to_string()))
260    }
261    #[inline]
262    fn message_static_message(msg: &'static str) -> Self {
263        Error::Message(Info::Static(msg))
264    }
265    #[inline]
266    fn message_token(token: Item) -> Self {
267        Error::Message(Info::Token(token))
268    }
269    #[inline]
270    fn message_range(token: Range) -> Self {
271        Error::Message(Info::Range(token))
272    }
273
274    fn is_unexpected_end_of_input(&self) -> bool {
275        *self == Self::end_of_input()
276    }
277
278    #[inline]
279    fn other<E>(err: E) -> Self
280    where
281        E: StdError + Send + Sync + 'static,
282    {
283        err.into()
284    }
285
286    #[inline]
287    fn into_other<T>(self) -> T
288    where
289        T: StreamError<Item, Range>,
290    {
291        match self {
292            Error::Unexpected(info) => match info {
293                Info::Token(x) => T::unexpected_token(x),
294                Info::Range(x) => T::unexpected_range(x),
295                Info::Static(x) => T::unexpected_static_message(x),
296                Info::Owned(x) => T::unexpected_format(x),
297            },
298            Error::Expected(info) => match info {
299                Info::Token(x) => T::expected_token(x),
300                Info::Range(x) => T::expected_range(x),
301                Info::Static(x) => T::expected_static_message(x),
302                Info::Owned(x) => T::expected_format(x),
303            },
304            Error::Message(info) => match info {
305                Info::Token(x) => T::expected_token(x),
306                Info::Range(x) => T::expected_range(x),
307                Info::Static(x) => T::expected_static_message(x),
308                Info::Owned(x) => T::expected_format(x),
309            },
310            Error::Other(err) => T::message_format(err),
311        }
312    }
313}
314
315impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position> for Error<Item, Range>
316where
317    Item: PartialEq,
318    Range: PartialEq,
319    Position: Default,
320{
321    type StreamError = Self;
322    #[inline]
323    fn empty(_: Position) -> Self {
324        Self::message_static_message("")
325    }
326    #[inline]
327    fn from_error(_: Position, err: Self::StreamError) -> Self {
328        err
329    }
330
331    #[inline]
332    fn position(&self) -> Position {
333        Position::default()
334    }
335
336    #[inline]
337    fn set_position(&mut self, _position: Position) {}
338
339    #[inline]
340    fn add(&mut self, err: Self::StreamError) {
341        *self = err;
342    }
343
344    #[inline]
345    fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
346    where
347        F: FnOnce(&mut Tracked<Self>),
348    {
349        f(self_);
350        self_.error = info;
351    }
352
353    fn is_unexpected_end_of_input(&self) -> bool {
354        *self == Self::end_of_input()
355    }
356
357    #[inline]
358    fn into_other<T>(self) -> T
359    where
360        T: crate::error::ParseError<Item, Range, Position>,
361    {
362        T::from_error(Position::default(), StreamError::into_other(self))
363    }
364}
365
366impl<Item, Range, Position> crate::error::ParseErrorInto<Item, Range, Position>
367    for Errors<Item, Range, Position>
368{
369    fn into_other_error<T, Item2, Range2, Position2>(self) -> T
370    where
371        T: crate::error::ParseError<Item2, Range2, Position2>,
372        Item2: From<Item>,
373        Range2: From<Range>,
374        Position2: From<Position>,
375    {
376        let mut error = T::empty(self.position.into());
377        for err in self.errors {
378            error.add(crate::error::StreamErrorInto::<Item, Range>::into_other_error(err));
379        }
380        error
381    }
382}
383
384impl<Item, Range> crate::error::StreamErrorInto<Item, Range> for Error<Item, Range> {
385    fn into_other_error<T, Item2, Range2>(self) -> T
386    where
387        T: crate::error::StreamError<Item2, Range2>,
388        Item2: From<Item>,
389        Range2: From<Range>,
390    {
391        match self {
392            Error::Unexpected(info) => match info {
393                Info::Token(x) => T::unexpected_token(x.into()),
394                Info::Range(x) => T::unexpected_range(x.into()),
395                Info::Static(x) => T::unexpected_static_message(x),
396                Info::Owned(x) => T::unexpected_format(x),
397            },
398            Error::Expected(info) => match info {
399                Info::Token(x) => T::expected_token(x.into()),
400                Info::Range(x) => T::expected_range(x.into()),
401                Info::Static(x) => T::expected_static_message(x),
402                Info::Owned(x) => T::expected_format(x),
403            },
404            Error::Message(info) => match info {
405                Info::Token(x) => T::expected_token(x.into()),
406                Info::Range(x) => T::expected_range(x.into()),
407                Info::Static(x) => T::expected_static_message(x),
408                Info::Owned(x) => T::expected_format(x),
409            },
410            Error::Other(err) => T::message_format(err),
411        }
412    }
413}
414
415impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position>
416    for Errors<Item, Range, Position>
417where
418    Item: PartialEq,
419    Range: PartialEq,
420    Position: Ord + Clone,
421{
422    type StreamError = Error<Item, Range>;
423    #[inline]
424    fn empty(pos: Position) -> Self {
425        Errors::empty(pos)
426    }
427    #[inline]
428    fn from_error(position: Position, err: Self::StreamError) -> Self {
429        Self::new(position, err)
430    }
431
432    #[inline]
433    fn position(&self) -> Position {
434        self.position.clone()
435    }
436
437    #[inline]
438    fn set_position(&mut self, position: Position) {
439        self.position = position;
440    }
441
442    #[inline]
443    fn merge(self, other: Self) -> Self {
444        Errors::merge(self, other)
445    }
446
447    #[inline]
448    fn add(&mut self, err: Self::StreamError) {
449        self.add_error(err);
450    }
451
452    #[inline]
453    fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
454    where
455        F: FnOnce(&mut Tracked<Self>),
456    {
457        let start = self_.error.errors.len();
458        f(self_);
459        // Replace all expected errors that were added from the previous add_error
460        // with this expected error
461        let mut i = 0;
462        self_.error.errors.retain(|e| {
463            if i < start {
464                i += 1;
465                true
466            } else {
467                match *e {
468                    Error::Expected(_) => false,
469                    _ => true,
470                }
471            }
472        });
473        self_.error.add(info);
474    }
475
476    fn clear_expected(&mut self) {
477        self.errors.retain(|e| match *e {
478            Error::Expected(_) => false,
479            _ => true,
480        })
481    }
482
483    fn is_unexpected_end_of_input(&self) -> bool {
484        self.errors
485            .iter()
486            .any(StreamError::is_unexpected_end_of_input)
487    }
488
489    #[inline]
490    fn into_other<T>(mut self) -> T
491    where
492        T: crate::error::ParseError<Item, Range, Position>,
493    {
494        match self.errors.pop() {
495            Some(err) => T::from_error(self.position, StreamError::into_other(err)),
496            None => T::empty(self.position),
497        }
498    }
499}
500
501impl<T, R> Error<T, R> {
502    pub fn map_token<F, U>(self, f: F) -> Error<U, R>
503    where
504        F: FnOnce(T) -> U,
505    {
506        use self::Error::*;
507
508        match self {
509            Unexpected(x) => Unexpected(x.map_token(f)),
510            Expected(x) => Expected(x.map_token(f)),
511            Message(x) => Message(x.map_token(f)),
512            Other(x) => Other(x),
513        }
514    }
515
516    pub fn map_range<F, S>(self, f: F) -> Error<T, S>
517    where
518        F: FnOnce(R) -> S,
519    {
520        use self::Error::*;
521
522        match self {
523            Unexpected(x) => Unexpected(x.map_range(f)),
524            Expected(x) => Expected(x.map_range(f)),
525            Message(x) => Message(x.map_range(f)),
526            Other(x) => Other(x),
527        }
528    }
529}
530
531impl<T: PartialEq, R: PartialEq> PartialEq for Error<T, R> {
532    fn eq(&self, other: &Error<T, R>) -> bool {
533        match (self, other) {
534            (&Error::Unexpected(ref l), &Error::Unexpected(ref r))
535            | (&Error::Expected(ref l), &Error::Expected(ref r))
536            | (&Error::Message(ref l), &Error::Message(ref r)) => l == r,
537            _ => false,
538        }
539    }
540}
541
542impl<T, R, E> From<E> for Error<T, R>
543where
544    E: StdError + 'static + Send + Sync,
545{
546    fn from(e: E) -> Error<T, R> {
547        Error::Other(Box::new(e))
548    }
549}
550
551impl<T, R> Error<T, R> {
552    /// Returns the `end_of_input` error.
553    pub fn end_of_input() -> Error<T, R> {
554        Error::Unexpected("end of input".into())
555    }
556
557    /// Formats a slice of errors in a human readable way.
558    ///
559    /// ```rust
560    /// # extern crate combine;
561    /// # use combine::*;
562    /// # use combine::parser::char::*;
563    /// # use combine::stream::position::{self, SourcePosition};
564    ///
565    /// # fn main() {
566    /// let input = r"
567    ///   ,123
568    /// ";
569    /// let result = spaces().silent().with(char('.').or(char('a')).or(digit()))
570    ///     .easy_parse(position::Stream::new(input));
571    /// let m = format!("{}", result.unwrap_err());
572    /// let expected = r"Parse error at line: 2, column: 3
573    /// Unexpected `,`
574    /// Expected `.`, `a` or digit
575    /// ";
576    /// assert_eq!(m, expected);
577    /// # }
578    /// ```
579    pub fn fmt_errors(errors: &[Error<T, R>], f: &mut fmt::Formatter<'_>) -> fmt::Result
580    where
581        T: fmt::Display,
582        R: fmt::Display,
583    {
584        // First print the token that we did not expect
585        // There should really just be one unexpected message at this point though we print them
586        // all to be safe
587        let unexpected = errors.iter().filter(|e| match **e {
588            Error::Unexpected(_) => true,
589            _ => false,
590        });
591        for error in unexpected {
592            writeln!(f, "{}", error)?;
593        }
594
595        // Then we print out all the things that were expected in a comma separated list
596        // 'Expected 'a', 'expression' or 'let'
597        let iter = || {
598            errors.iter().filter_map(|e| match *e {
599                Error::Expected(ref err) => Some(err),
600                _ => None,
601            })
602        };
603        let expected_count = iter().count();
604        for (i, message) in iter().enumerate() {
605            let s = match i {
606                0 => "Expected",
607                _ if i < expected_count - 1 => ",",
608                // Last expected message to be written
609                _ => " or",
610            };
611            write!(f, "{} {}", s, message)?;
612        }
613        if expected_count != 0 {
614            writeln!(f)?;
615        }
616        // If there are any generic messages we print them out last
617        let messages = errors.iter().filter(|e| match **e {
618            Error::Message(_) | Error::Other(_) => true,
619            _ => false,
620        });
621        for error in messages {
622            writeln!(f, "{}", error)?;
623        }
624        Ok(())
625    }
626}
627
628/// Convenience alias over `Errors` for `StreamOnce` types which makes it possible to specify the
629/// `Errors` type from a `StreamOnce` by writing `ParseError<Input>` instead of `Errors<Input::Token,
630/// Input::Range, Input::Position>`
631pub type ParseError<S> =
632    Errors<<S as StreamOnce>::Token, <S as StreamOnce>::Range, <S as StreamOnce>::Position>;
633
634/// Struct which hold information about an error that occurred at a specific position.
635/// Can hold multiple instances of `Error` if more that one error occurred in the same position.
636#[derive(Debug, PartialEq)]
637pub struct Errors<T, R, P> {
638    /// The position where the error occurred
639    pub position: P,
640    /// A vector containing specific information on what errors occurred at `position`. Usually
641    /// a fully formed message contains one `Unexpected` error and one or more `Expected` errors.
642    /// `Message` and `Other` may also appear (`combine` never generates these errors on its own)
643    /// and may warrant custom handling.
644    pub errors: Vec<Error<T, R>>,
645}
646
647impl<T, R, P> Errors<T, R, P> {
648    /// Constructs a new `ParseError` which occurred at `position`.
649    #[inline]
650    pub fn new(position: P, error: Error<T, R>) -> Errors<T, R, P> {
651        Self::from_errors(position, vec![error])
652    }
653
654    /// Constructs an error with no other information than the position it occurred at.
655    #[inline]
656    pub fn empty(position: P) -> Errors<T, R, P> {
657        Self::from_errors(position, vec![])
658    }
659
660    /// Constructs a `ParseError` with multiple causes.
661    #[inline]
662    pub fn from_errors(position: P, errors: Vec<Error<T, R>>) -> Errors<T, R, P> {
663        Errors { position, errors }
664    }
665
666    /// Constructs an end of input error. Should be returned by parsers which encounter end of
667    /// input unexpectedly.
668    #[inline]
669    pub fn end_of_input(position: P) -> Errors<T, R, P> {
670        Self::new(position, Error::end_of_input())
671    }
672
673    /// Adds an error if `error` does not exist in this `ParseError` already (as determined byte
674    /// `PartialEq`).
675    pub fn add_error(&mut self, error: Error<T, R>)
676    where
677        T: PartialEq,
678        R: PartialEq,
679    {
680        // Don't add duplicate errors
681        if self.errors.iter().all(|err| *err != error) {
682            self.errors.push(error);
683        }
684    }
685
686    /// Removes all `Expected` errors in `self` and adds `info` instead.
687    pub fn set_expected(&mut self, info: Info<T, R>) {
688        // Remove all other expected messages
689        self.errors.retain(|e| match *e {
690            Error::Expected(_) => false,
691            _ => true,
692        });
693        self.errors.push(Error::Expected(info));
694    }
695
696    /// Merges two `ParseError`s. If they exist at the same position the errors of `other` are
697    /// added to `self` (using `add_error` to skip duplicates). If they are not at the same
698    /// position the error furthest ahead are returned, ignoring the other `ParseError`.
699    pub fn merge(mut self, mut other: Errors<T, R, P>) -> Errors<T, R, P>
700    where
701        P: Ord,
702        T: PartialEq,
703        R: PartialEq,
704    {
705        use std::cmp::Ordering;
706
707        // Only keep the errors which occurred after consuming the most amount of data
708        match self.position.cmp(&other.position) {
709            Ordering::Less => other,
710            Ordering::Greater => self,
711            Ordering::Equal => {
712                for message in other.errors.drain(..) {
713                    self.add_error(message);
714                }
715                self
716            }
717        }
718    }
719
720    /// Maps the position to a new value
721    pub fn map_position<F, Q>(self, f: F) -> Errors<T, R, Q>
722    where
723        F: FnOnce(P) -> Q,
724    {
725        Errors::from_errors(f(self.position), self.errors)
726    }
727
728    /// Maps all token variants to a new value
729    pub fn map_token<F, U>(self, mut f: F) -> Errors<U, R, P>
730    where
731        F: FnMut(T) -> U,
732    {
733        Errors::from_errors(
734            self.position,
735            self.errors
736                .into_iter()
737                .map(|error| error.map_token(&mut f))
738                .collect(),
739        )
740    }
741
742    /// Maps all range variants to a new value.
743    ///
744    /// ```
745    /// use combine::*;
746    /// use combine::parser::range::range;
747    /// println!(
748    ///     "{}",
749    ///     range(&"HTTP"[..])
750    ///         .easy_parse("HTT")
751    ///         .unwrap_err()
752    ///         .map_range(|bytes| format!("{:?}", bytes))
753    /// );
754    /// ```
755    pub fn map_range<F, S>(self, mut f: F) -> Errors<T, S, P>
756    where
757        F: FnMut(R) -> S,
758    {
759        Errors::from_errors(
760            self.position,
761            self.errors
762                .into_iter()
763                .map(|error| error.map_range(&mut f))
764                .collect(),
765        )
766    }
767}
768
769impl<T, R, P> StdError for Errors<T, R, P>
770where
771    P: fmt::Display + fmt::Debug,
772    T: fmt::Display + fmt::Debug,
773    R: fmt::Display + fmt::Debug,
774{
775    fn description(&self) -> &str {
776        "parse error"
777    }
778}
779
780impl<T, R, P> fmt::Display for Errors<T, R, P>
781where
782    P: fmt::Display,
783    T: fmt::Display,
784    R: fmt::Display,
785{
786    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787        writeln!(f, "Parse error at {}", self.position)?;
788        Error::fmt_errors(&self.errors, f)
789    }
790}
791
792impl<T: fmt::Display, R: fmt::Display> fmt::Display for Error<T, R> {
793    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
794        match *self {
795            Error::Unexpected(ref c) => write!(f, "Unexpected {}", c),
796            Error::Expected(ref s) => write!(f, "Expected {}", s),
797            Error::Message(ref msg) => msg.fmt(f),
798            Error::Other(ref err) => err.fmt(f),
799        }
800    }
801}
802
803#[derive(PartialEq, Eq, Copy, Clone, Debug)]
804pub struct Stream<S>(pub S);
805
806impl<S> From<S> for Stream<S> {
807    fn from(stream: S) -> Self {
808        Stream(stream)
809    }
810}
811
812impl<S> ResetStream for Stream<S>
813where
814    S: ResetStream + Positioned,
815    S::Token: PartialEq,
816    S::Range: PartialEq,
817{
818    type Checkpoint = S::Checkpoint;
819
820    fn checkpoint(&self) -> Self::Checkpoint {
821        self.0.checkpoint()
822    }
823    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
824        self.0
825            .reset(checkpoint)
826            .map_err(crate::error::ParseError::into_other)
827    }
828}
829
830impl<S> StreamOnce for Stream<S>
831where
832    S: StreamOnce + Positioned,
833    S::Token: PartialEq,
834    S::Range: PartialEq,
835{
836    type Token = S::Token;
837    type Range = S::Range;
838    type Position = S::Position;
839    type Error = ParseError<S>;
840
841    #[inline]
842    fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> {
843        self.0.uncons().map_err(StreamError::into_other)
844    }
845
846    fn is_partial(&self) -> bool {
847        self.0.is_partial()
848    }
849}
850
851impl<S> RangeStreamOnce for Stream<S>
852where
853    S: RangeStream,
854    S::Token: PartialEq,
855    S::Range: PartialEq,
856{
857    #[inline]
858    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
859        self.0.uncons_range(size).map_err(StreamError::into_other)
860    }
861
862    #[inline]
863    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
864    where
865        F: FnMut(Self::Token) -> bool,
866    {
867        self.0.uncons_while(f).map_err(StreamError::into_other)
868    }
869
870    #[inline]
871    fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
872    where
873        F: FnMut(Self::Token) -> bool,
874    {
875        self.0.uncons_while1(f).map_err(StreamError::into_other)
876    }
877
878    #[inline]
879    fn distance(&self, end: &Self::Checkpoint) -> usize {
880        self.0.distance(end)
881    }
882
883    fn range(&self) -> Self::Range {
884        self.0.range()
885    }
886}
887
888impl<S> Positioned for Stream<S>
889where
890    S: StreamOnce + Positioned,
891    S::Token: PartialEq,
892    S::Range: PartialEq,
893{
894    fn position(&self) -> S::Position {
895        self.0.position()
896    }
897}