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