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 83 use std::{error::Error as StdError, fmt}; 84 85 use crate::error::{Info as PrimitiveInfo, ParseResult, StreamError, Tracked}; 86 87 use 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)] 98 pub enum Info<T, R> { 99 Token(T), 100 Range(R), 101 Owned(String), 102 Static(&'static str), 103 } 104 105 impl<T, R, F> From<PrimitiveInfo<T, R, F>> for Info<T, R> 106 where 107 F: fmt::Display, 108 { from(info: PrimitiveInfo<T, R, F>) -> Self109 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 119 impl<T, R> Info<T, R> { map_token<F, U>(self, f: F) -> Info<U, R> where F: FnOnce(T) -> U,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 map_range<F, S>(self, f: F) -> Info<T, S> where F: FnOnce(R) -> S,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 149 impl<T: PartialEq, R: PartialEq> PartialEq for Info<T, R> { eq(&self, other: &Info<T, R>) -> bool150 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 } 162 impl<T: fmt::Display, R: fmt::Display> fmt::Display for Info<T, R> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result163 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 173 impl<R> From<char> for Info<char, R> { from(s: char) -> Info<char, R>174 fn from(s: char) -> Info<char, R> { 175 Info::Token(s) 176 } 177 } 178 impl<T, R> From<String> for Info<T, R> { from(s: String) -> Info<T, R>179 fn from(s: String) -> Info<T, R> { 180 Info::Owned(s) 181 } 182 } 183 184 impl<T, R> From<&'static str> for Info<T, R> { from(s: &'static str) -> Info<T, R>185 fn from(s: &'static str) -> Info<T, R> { 186 Info::Static(s) 187 } 188 } 189 190 impl<R> From<u8> for Info<u8, R> { from(s: u8) -> 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)] 198 pub 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 209 impl<Item, Range> StreamError<Item, Range> for Error<Item, Range> 210 where 211 Item: PartialEq, 212 Range: PartialEq, 213 { 214 #[inline] unexpected_token(token: Item) -> Self215 fn unexpected_token(token: Item) -> Self { 216 Error::Unexpected(Info::Token(token)) 217 } 218 #[inline] unexpected_range(token: Range) -> Self219 fn unexpected_range(token: Range) -> Self { 220 Error::Unexpected(Info::Range(token)) 221 } 222 #[inline] unexpected_format<T>(msg: T) -> Self where T: fmt::Display,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] unexpected_static_message(msg: &'static str) -> Self230 fn unexpected_static_message(msg: &'static str) -> Self { 231 Error::Unexpected(Info::Static(msg)) 232 } 233 234 #[inline] expected_token(token: Item) -> Self235 fn expected_token(token: Item) -> Self { 236 Error::Expected(Info::Token(token)) 237 } 238 #[inline] expected_range(token: Range) -> Self239 fn expected_range(token: Range) -> Self { 240 Error::Expected(Info::Range(token)) 241 } 242 #[inline] expected_format<T>(msg: T) -> Self where T: fmt::Display,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] expected_static_message(msg: &'static str) -> Self250 fn expected_static_message(msg: &'static str) -> Self { 251 Error::Expected(Info::Static(msg)) 252 } 253 254 #[inline] message_format<T>(msg: T) -> Self where T: fmt::Display,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] message_static_message(msg: &'static str) -> Self262 fn message_static_message(msg: &'static str) -> Self { 263 Error::Message(Info::Static(msg)) 264 } 265 #[inline] message_token(token: Item) -> Self266 fn message_token(token: Item) -> Self { 267 Error::Message(Info::Token(token)) 268 } 269 #[inline] message_range(token: Range) -> Self270 fn message_range(token: Range) -> Self { 271 Error::Message(Info::Range(token)) 272 } 273 is_unexpected_end_of_input(&self) -> bool274 fn is_unexpected_end_of_input(&self) -> bool { 275 *self == Self::end_of_input() 276 } 277 278 #[inline] other<E>(err: E) -> Self where E: StdError + Send + Sync + 'static,279 fn other<E>(err: E) -> Self 280 where 281 E: StdError + Send + Sync + 'static, 282 { 283 err.into() 284 } 285 286 #[inline] into_other<T>(self) -> T where T: StreamError<Item, Range>,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 315 impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position> for Error<Item, Range> 316 where 317 Item: PartialEq, 318 Range: PartialEq, 319 Position: Default, 320 { 321 type StreamError = Self; 322 #[inline] empty(_: Position) -> Self323 fn empty(_: Position) -> Self { 324 Self::message_static_message("") 325 } 326 #[inline] from_error(_: Position, err: Self::StreamError) -> Self327 fn from_error(_: Position, err: Self::StreamError) -> Self { 328 err 329 } 330 331 #[inline] position(&self) -> Position332 fn position(&self) -> Position { 333 Position::default() 334 } 335 336 #[inline] set_position(&mut self, _position: Position)337 fn set_position(&mut self, _position: Position) {} 338 339 #[inline] add(&mut self, err: Self::StreamError)340 fn add(&mut self, err: Self::StreamError) { 341 *self = err; 342 } 343 344 #[inline] set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F) where F: FnOnce(&mut Tracked<Self>),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 is_unexpected_end_of_input(&self) -> bool353 fn is_unexpected_end_of_input(&self) -> bool { 354 *self == Self::end_of_input() 355 } 356 357 #[inline] into_other<T>(self) -> T where T: crate::error::ParseError<Item, Range, Position>,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 366 impl<Item, Range, Position> crate::error::ParseErrorInto<Item, Range, Position> 367 for Errors<Item, Range, Position> 368 { into_other_error<T, Item2, Range2, Position2>(self) -> T where T: crate::error::ParseError<Item2, Range2, Position2>, Item2: From<Item>, Range2: From<Range>, Position2: From<Position>,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 384 impl<Item, Range> crate::error::StreamErrorInto<Item, Range> for Error<Item, Range> { into_other_error<T, Item2, Range2>(self) -> T where T: crate::error::StreamError<Item2, Range2>, Item2: From<Item>, Range2: From<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 415 impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position> 416 for Errors<Item, Range, Position> 417 where 418 Item: PartialEq, 419 Range: PartialEq, 420 Position: Ord + Clone, 421 { 422 type StreamError = Error<Item, Range>; 423 #[inline] empty(pos: Position) -> Self424 fn empty(pos: Position) -> Self { 425 Errors::empty(pos) 426 } 427 #[inline] from_error(position: Position, err: Self::StreamError) -> Self428 fn from_error(position: Position, err: Self::StreamError) -> Self { 429 Self::new(position, err) 430 } 431 432 #[inline] position(&self) -> Position433 fn position(&self) -> Position { 434 self.position.clone() 435 } 436 437 #[inline] set_position(&mut self, position: Position)438 fn set_position(&mut self, position: Position) { 439 self.position = position; 440 } 441 442 #[inline] merge(self, other: Self) -> Self443 fn merge(self, other: Self) -> Self { 444 Errors::merge(self, other) 445 } 446 447 #[inline] add(&mut self, err: Self::StreamError)448 fn add(&mut self, err: Self::StreamError) { 449 self.add_error(err); 450 } 451 452 #[inline] set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F) where F: FnOnce(&mut Tracked<Self>),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 clear_expected(&mut self)476 fn clear_expected(&mut self) { 477 self.errors.retain(|e| match *e { 478 Error::Expected(_) => false, 479 _ => true, 480 }) 481 } 482 is_unexpected_end_of_input(&self) -> bool483 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] into_other<T>(mut self) -> T where T: crate::error::ParseError<Item, Range, Position>,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 501 impl<T, R> Error<T, R> { map_token<F, U>(self, f: F) -> Error<U, R> where F: FnOnce(T) -> U,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 map_range<F, S>(self, f: F) -> Error<T, S> where F: FnOnce(R) -> S,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 531 impl<T: PartialEq, R: PartialEq> PartialEq for Error<T, R> { eq(&self, other: &Error<T, R>) -> bool532 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 542 impl<T, R, E> From<E> for Error<T, R> 543 where 544 E: StdError + 'static + Send + Sync, 545 { from(e: E) -> Error<T, R>546 fn from(e: E) -> Error<T, R> { 547 Error::Other(Box::new(e)) 548 } 549 } 550 551 impl<T, R> Error<T, R> { 552 /// Returns the `end_of_input` error. end_of_input() -> Error<T, R>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 /// ``` fmt_errors(errors: &[Error<T, R>], f: &mut fmt::Formatter<'_>) -> fmt::Result where T: fmt::Display, R: fmt::Display,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>` 631 pub 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)] 637 pub 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 647 impl<T, R, P> Errors<T, R, P> { 648 /// Constructs a new `ParseError` which occurred at `position`. 649 #[inline] new(position: P, error: Error<T, R>) -> Errors<T, R, P>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] empty(position: P) -> Errors<T, R, P>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] from_errors(position: P, errors: Vec<Error<T, R>>) -> Errors<T, R, P>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] end_of_input(position: P) -> Errors<T, R, P>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`). add_error(&mut self, error: Error<T, R>) where T: PartialEq, R: 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. set_expected(&mut self, info: Info<T, R>)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`. merge(mut self, mut other: Errors<T, R, P>) -> Errors<T, R, P> where P: Ord, T: PartialEq, R: PartialEq,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 map_position<F, Q>(self, f: F) -> Errors<T, R, Q> where F: FnOnce(P) -> Q,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 map_token<F, U>(self, mut f: F) -> Errors<U, R, P> where F: FnMut(T) -> U,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 /// ``` map_range<F, S>(self, mut f: F) -> Errors<T, S, P> where F: FnMut(R) -> S,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 769 impl<T, R, P> StdError for Errors<T, R, P> 770 where 771 P: fmt::Display + fmt::Debug, 772 T: fmt::Display + fmt::Debug, 773 R: fmt::Display + fmt::Debug, 774 { description(&self) -> &str775 fn description(&self) -> &str { 776 "parse error" 777 } 778 } 779 780 impl<T, R, P> fmt::Display for Errors<T, R, P> 781 where 782 P: fmt::Display, 783 T: fmt::Display, 784 R: fmt::Display, 785 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result786 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 792 impl<T: fmt::Display, R: fmt::Display> fmt::Display for Error<T, R> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result793 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)] 804 pub struct Stream<S>(pub S); 805 806 impl<S> From<S> for Stream<S> { from(stream: S) -> Self807 fn from(stream: S) -> Self { 808 Stream(stream) 809 } 810 } 811 812 impl<S> ResetStream for Stream<S> 813 where 814 S: ResetStream + Positioned, 815 S::Token: PartialEq, 816 S::Range: PartialEq, 817 { 818 type Checkpoint = S::Checkpoint; 819 checkpoint(&self) -> Self::Checkpoint820 fn checkpoint(&self) -> Self::Checkpoint { 821 self.0.checkpoint() 822 } reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error>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 830 impl<S> StreamOnce for Stream<S> 831 where 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] uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>>842 fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> { 843 self.0.uncons().map_err(StreamError::into_other) 844 } 845 is_partial(&self) -> bool846 fn is_partial(&self) -> bool { 847 self.0.is_partial() 848 } 849 } 850 851 impl<S> RangeStreamOnce for Stream<S> 852 where 853 S: RangeStream, 854 S::Token: PartialEq, 855 S::Range: PartialEq, 856 { 857 #[inline] uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>>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] uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>> where F: FnMut(Self::Token) -> bool,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] uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>> where F: FnMut(Self::Token) -> bool,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] distance(&self, end: &Self::Checkpoint) -> usize879 fn distance(&self, end: &Self::Checkpoint) -> usize { 880 self.0.distance(end) 881 } 882 range(&self) -> Self::Range883 fn range(&self) -> Self::Range { 884 self.0.range() 885 } 886 } 887 888 impl<S> Positioned for Stream<S> 889 where 890 S: StreamOnce + Positioned, 891 S::Token: PartialEq, 892 S::Range: PartialEq, 893 { position(&self) -> S::Position894 fn position(&self) -> S::Position { 895 self.0.position() 896 } 897 } 898