//! Parsers which cause errors or modifies the returned error on parse failure. use crate::{ error::{ ErrorInfo, ParseError, ParseResult::{self, *}, StreamError, Tracked, }, lib::marker::PhantomData, parser::ParseMode, Parser, Stream, StreamOnce, }; #[derive(Clone)] pub struct Unexpected(E, PhantomData (I, T)>) where I: Stream; impl Parser for Unexpected where Input: Stream, E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { type Output = T; type PartialState = (); #[inline] fn parse_lazy(&mut self, input: &mut Input) -> ParseResult::Error> { PeekErr(::Error::empty(input.position()).into()) } fn add_error(&mut self, errors: &mut Tracked<::Error>) { errors.error.add(StreamError::unexpected(&self.0)); } } /// Always fails with `message` as an unexpected error. /// Never consumes any input. /// /// Has `()` the output type /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::error::StreamError; /// # fn main() { /// let result = unexpected("token") /// .easy_parse("a"); /// assert!(result.is_err()); /// assert!( /// result.err() /// .unwrap() /// .errors /// .iter() /// .any(|m| *m == StreamError::unexpected("token")) /// ); /// # } /// ``` pub fn unexpected(message: S) -> Unexpected where Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { unexpected_any(message) } /// Always fails with `message` as an unexpected error. /// Never consumes any input. /// /// May have anything as the output type but must be used such that the output type can inferred. /// The `unexpected` parser can be used if the output type does not matter /// /// ``` /// # extern crate combine; /// # use combine::*; /// # use combine::parser::error::unexpected_any; /// # use combine::error::StreamError; /// # fn main() { /// let result = token('b').or(unexpected_any("token")) /// .easy_parse("a"); /// assert!(result.is_err()); /// assert!( /// result.err() /// .unwrap() /// .errors /// .iter() /// .any(|m| *m == StreamError::unexpected("token")) /// ); /// # } /// ``` pub fn unexpected_any(message: S) -> Unexpected where Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { Unexpected(message, PhantomData) } #[derive(Clone)] pub struct Message(P, S); impl Parser for Message where Input: Stream, P: Parser, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { type Output = P::Output; type PartialState = P::PartialState; parse_mode!(Input); #[inline] fn parse_mode_impl( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, { match self.0.parse_mode(mode, input, state) { CommitOk(x) => CommitOk(x), PeekOk(x) => PeekOk(x), // The message should always be added even if some input was committed before failing CommitErr(mut err) => { err.add_message(&self.1); CommitErr(err) } // The message will be added in `add_error` PeekErr(err) => PeekErr(err), } } fn add_error(&mut self, errors: &mut Tracked<::Error>) { self.0.add_error(errors); errors.error.add_message(&self.1); } forward_parser!(Input, parser_count add_committed_expected_error, 0); } /// Equivalent to [`p1.message(msg)`]. /// /// [`p1.message(msg)`]: ../trait.Parser.html#method.message pub fn message(p: P, msg: S) -> Message where P: Parser, Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { Message(p, msg) } #[derive(Clone)] pub struct Expected(P, S); impl Parser for Expected where P: Parser, Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { type Output = P::Output; type PartialState = P::PartialState; parse_mode!(Input); #[inline] fn parse_mode_impl( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, { self.0.parse_mode(mode, input, state) } fn add_error(&mut self, errors: &mut Tracked<::Error>) { ParseError::set_expected(errors, StreamError::expected(&self.1), |errors| { self.0.add_error(errors); }) } forward_parser!(Input, parser_count add_committed_expected_error, 0); } /// Equivalent to [`p.expected(info)`]. /// /// [`p.expected(info)`]: ../trait.Parser.html#method.expected pub fn expected(p: P, info: S) -> Expected where P: Parser, Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>, { Expected(p, info) } #[derive(Clone)] pub struct Silent

(P); impl Parser for Silent

where P: Parser, Input: Stream, { type Output = P::Output; type PartialState = P::PartialState; parse_mode!(Input); #[inline] fn parse_mode_impl( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult::Error> where M: ParseMode, { self.0.parse_mode(mode, input, state).map_err(|mut err| { err.clear_expected(); err }) } fn add_error(&mut self, _errors: &mut Tracked<::Error>) {} fn add_committed_expected_error( &mut self, _errors: &mut Tracked<::Error>, ) { } forward_parser!(Input, parser_count, 0); } /// Equivalent to [`p.silent()`]. /// /// [`p.silent()`]: ../trait.Parser.html#method.silent pub fn silent(p: P) -> Silent

where P: Parser, Input: Stream, { Silent(p) }