1 //! Parsers which cause errors or modifies the returned error on parse failure.
2 
3 use crate::{
4     error::{
5         ErrorInfo, ParseError,
6         ParseResult::{self, *},
7         StreamError, Tracked,
8     },
9     lib::marker::PhantomData,
10     parser::ParseMode,
11     Parser, Stream, StreamOnce,
12 };
13 
14 #[derive(Clone)]
15 pub struct Unexpected<I, T, E>(E, PhantomData<fn(I) -> (I, T)>)
16 where
17     I: Stream;
18 impl<Input, T, E> Parser<Input> for Unexpected<Input, T, E>
19 where
20     Input: Stream,
21     E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
22 {
23     type Output = T;
24     type PartialState = ();
25     #[inline]
parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, <Input as StreamOnce>::Error>26     fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, <Input as StreamOnce>::Error> {
27         PeekErr(<Input as StreamOnce>::Error::empty(input.position()).into())
28     }
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)29     fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
30         errors.error.add(StreamError::unexpected(&self.0));
31     }
32 }
33 /// Always fails with `message` as an unexpected error.
34 /// Never consumes any input.
35 ///
36 /// Has `()` the output type
37 ///
38 /// ```
39 /// # extern crate combine;
40 /// # use combine::*;
41 /// # use combine::error::StreamError;
42 /// # fn main() {
43 /// let result = unexpected("token")
44 ///     .easy_parse("a");
45 /// assert!(result.is_err());
46 /// assert!(
47 ///     result.err()
48 ///         .unwrap()
49 ///         .errors
50 ///         .iter()
51 ///         .any(|m| *m == StreamError::unexpected("token"))
52 /// );
53 /// # }
54 /// ```
unexpected<Input, S>(message: S) -> Unexpected<Input, (), S> where Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,55 pub fn unexpected<Input, S>(message: S) -> Unexpected<Input, (), S>
56 where
57     Input: Stream,
58     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
59 {
60     unexpected_any(message)
61 }
62 
63 /// Always fails with `message` as an unexpected error.
64 /// Never consumes any input.
65 ///
66 /// May have anything as the output type but must be used such that the output type can inferred.
67 /// The `unexpected` parser can be used if the output type does not matter
68 ///
69 /// ```
70 /// # extern crate combine;
71 /// # use combine::*;
72 /// # use combine::parser::error::unexpected_any;
73 /// # use combine::error::StreamError;
74 /// # fn main() {
75 /// let result = token('b').or(unexpected_any("token"))
76 ///     .easy_parse("a");
77 /// assert!(result.is_err());
78 /// assert!(
79 ///     result.err()
80 ///         .unwrap()
81 ///         .errors
82 ///         .iter()
83 ///         .any(|m| *m == StreamError::unexpected("token"))
84 /// );
85 /// # }
86 /// ```
unexpected_any<Input, S, T>(message: S) -> Unexpected<Input, T, S> where Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,87 pub fn unexpected_any<Input, S, T>(message: S) -> Unexpected<Input, T, S>
88 where
89     Input: Stream,
90     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
91 {
92     Unexpected(message, PhantomData)
93 }
94 
95 #[derive(Clone)]
96 pub struct Message<P, S>(P, S);
97 impl<Input, P, S> Parser<Input> for Message<P, S>
98 where
99     Input: Stream,
100     P: Parser<Input>,
101     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
102 {
103     type Output = P::Output;
104     type PartialState = P::PartialState;
105 
106     parse_mode!(Input);
107     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,108     fn parse_mode_impl<M>(
109         &mut self,
110         mode: M,
111         input: &mut Input,
112         state: &mut Self::PartialState,
113     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
114     where
115         M: ParseMode,
116     {
117         match self.0.parse_mode(mode, input, state) {
118             CommitOk(x) => CommitOk(x),
119             PeekOk(x) => PeekOk(x),
120 
121             // The message should always be added even if some input was committed before failing
122             CommitErr(mut err) => {
123                 err.add_message(&self.1);
124                 CommitErr(err)
125             }
126 
127             // The message will be added in `add_error`
128             PeekErr(err) => PeekErr(err),
129         }
130     }
131 
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)132     fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
133         self.0.add_error(errors);
134         errors.error.add_message(&self.1);
135     }
136 
137     forward_parser!(Input, parser_count add_committed_expected_error, 0);
138 }
139 
140 /// Equivalent to [`p1.message(msg)`].
141 ///
142 /// [`p1.message(msg)`]: ../trait.Parser.html#method.message
message<Input, P, S>(p: P, msg: S) -> Message<P, S> where P: Parser<Input>, Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,143 pub fn message<Input, P, S>(p: P, msg: S) -> Message<P, S>
144 where
145     P: Parser<Input>,
146     Input: Stream,
147     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
148 {
149     Message(p, msg)
150 }
151 
152 #[derive(Clone)]
153 pub struct Expected<P, S>(P, S);
154 impl<Input, P, S> Parser<Input> for Expected<P, S>
155 where
156     P: Parser<Input>,
157     Input: Stream,
158     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
159 {
160     type Output = P::Output;
161     type PartialState = P::PartialState;
162 
163     parse_mode!(Input);
164     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,165     fn parse_mode_impl<M>(
166         &mut self,
167         mode: M,
168         input: &mut Input,
169         state: &mut Self::PartialState,
170     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
171     where
172         M: ParseMode,
173     {
174         self.0.parse_mode(mode, input, state)
175     }
176 
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)177     fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
178         ParseError::set_expected(errors, StreamError::expected(&self.1), |errors| {
179             self.0.add_error(errors);
180         })
181     }
182 
183     forward_parser!(Input, parser_count add_committed_expected_error, 0);
184 }
185 
186 /// Equivalent to [`p.expected(info)`].
187 ///
188 /// [`p.expected(info)`]: ../trait.Parser.html#method.expected
expected<Input, P, S>(p: P, info: S) -> Expected<P, S> where P: Parser<Input>, Input: Stream, S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,189 pub fn expected<Input, P, S>(p: P, info: S) -> Expected<P, S>
190 where
191     P: Parser<Input>,
192     Input: Stream,
193     S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
194 {
195     Expected(p, info)
196 }
197 
198 #[derive(Clone)]
199 pub struct Silent<P>(P);
200 impl<Input, P> Parser<Input> for Silent<P>
201 where
202     P: Parser<Input>,
203     Input: Stream,
204 {
205     type Output = P::Output;
206     type PartialState = P::PartialState;
207 
208     parse_mode!(Input);
209     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,210     fn parse_mode_impl<M>(
211         &mut self,
212         mode: M,
213         input: &mut Input,
214         state: &mut Self::PartialState,
215     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
216     where
217         M: ParseMode,
218     {
219         self.0.parse_mode(mode, input, state).map_err(|mut err| {
220             err.clear_expected();
221             err
222         })
223     }
224 
add_error(&mut self, _errors: &mut Tracked<<Input as StreamOnce>::Error>)225     fn add_error(&mut self, _errors: &mut Tracked<<Input as StreamOnce>::Error>) {}
226 
add_committed_expected_error( &mut self, _errors: &mut Tracked<<Input as StreamOnce>::Error>, )227     fn add_committed_expected_error(
228         &mut self,
229         _errors: &mut Tracked<<Input as StreamOnce>::Error>,
230     ) {
231     }
232 
233     forward_parser!(Input, parser_count, 0);
234 }
235 
236 /// Equivalent to [`p.silent()`].
237 ///
238 /// [`p.silent()`]: ../trait.Parser.html#method.silent
silent<Input, P>(p: P) -> Silent<P> where P: Parser<Input>, Input: Stream,239 pub fn silent<Input, P>(p: P) -> Silent<P>
240 where
241     P: Parser<Input>,
242     Input: Stream,
243 {
244     Silent(p)
245 }
246