blob: a0c25f74b80b021a0d74274436e22f1e76f94043 [file] [log] [blame]
Ivan Lozano57e660e2021-08-20 09:58:42 -04001//! 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}