1use crate::debug::error::debug_parse_error;
14use crate::debug::{restrict, DebugWidth};
15use crate::prelude::SpanFragment;
16use crate::{Code, ErrOrNomErr, KParseError};
17use nom::error::ErrorKind;
18use nom::{InputIter, InputLength, InputTake};
19use std::any::Any;
20#[cfg(debug_assertions)]
21use std::backtrace::Backtrace;
22use std::error::Error;
23use std::fmt;
24use std::fmt::{Debug, Display};
25
26pub struct ParserError<C, I> {
28 pub code: C,
30 pub span: I,
32 pub hints: Vec<Hints<C, I>>,
34 #[cfg(debug_assertions)]
35 pub backtrace: Backtrace,
36}
37
38pub enum Hints<C, I> {
40 Expect(SpanAndCode<C, I>),
42 Suggest(SpanAndCode<C, I>),
44 Cause(Box<dyn Error>),
46 UserData(Box<dyn Any>),
48}
49
50impl<C, I> ErrOrNomErr for ParserError<C, I>
51where
52 C: Code,
53 I: Clone + Debug + SpanFragment,
54 I: InputTake + InputLength + InputIter,
55{
56 type WrappedError = ParserError<C, I>;
57
58 fn wrap(self) -> nom::Err<Self::WrappedError> {
59 nom::Err::Error(self)
60 }
61}
62
63impl<C, I> ErrOrNomErr for nom::Err<ParserError<C, I>>
64where
65 C: Code,
66 I: Clone + Debug + SpanFragment,
67 I: InputTake + InputLength + InputIter,
68{
69 type WrappedError = ParserError<C, I>;
70
71 fn wrap(self) -> nom::Err<Self::WrappedError> {
72 self
73 }
74}
75
76impl<C, I> KParseError<C, I> for ParserError<C, I>
77where
78 C: Code,
79 I: Clone + Debug + SpanFragment,
80 I: InputTake + InputLength + InputIter,
81{
82 type WrappedError = ParserError<C, I>;
83
84 fn from(code: C, span: I) -> Self {
85 ParserError::new(code, span)
86 }
87
88 fn with_code(self, code: C) -> Self {
89 ParserError::with_code(self, code)
90 }
91
92 fn code(&self) -> Option<C> {
93 Some(self.code)
94 }
95
96 fn span(&self) -> Option<I> {
97 Some(self.span.clone())
98 }
99
100 fn err(&self) -> Option<&Self::WrappedError> {
101 Some(self)
102 }
103
104 fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
105 Some((self.code, self.span.clone(), self))
106 }
107}
108
109impl<C, I> KParseError<C, I> for nom::Err<ParserError<C, I>>
110where
111 C: Code,
112 I: Clone + Debug + SpanFragment,
113 I: InputTake + InputLength + InputIter,
114{
115 type WrappedError = ParserError<C, I>;
116
117 fn from(code: C, span: I) -> Self {
118 nom::Err::Error(KParseError::from(code, span))
119 }
120
121 fn with_code(self, code: C) -> Self {
122 match self {
123 nom::Err::Incomplete(_) => self,
124 nom::Err::Error(e) => nom::Err::Error(e.with_code(code)),
125 nom::Err::Failure(e) => nom::Err::Failure(e.with_code(code)),
126 }
127 }
128
129 fn code(&self) -> Option<C> {
130 match self {
131 nom::Err::Incomplete(_) => None,
132 nom::Err::Error(e) => Some(e.code),
133 nom::Err::Failure(e) => Some(e.code),
134 }
135 }
136
137 fn span(&self) -> Option<I> {
138 match self {
139 nom::Err::Incomplete(_) => None,
140 nom::Err::Error(e) => Some(e.span.clone()),
141 nom::Err::Failure(e) => Some(e.span.clone()),
142 }
143 }
144
145 fn err(&self) -> Option<&Self::WrappedError> {
146 match self {
147 nom::Err::Incomplete(_) => None,
148 nom::Err::Error(e) => Some(e),
149 nom::Err::Failure(e) => Some(e),
150 }
151 }
152
153 fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
154 match self {
155 nom::Err::Incomplete(_) => None,
156 nom::Err::Error(e) => Some((e.code, e.span.clone(), e)),
157 nom::Err::Failure(e) => Some((e.code, e.span.clone(), e)),
158 }
159 }
160}
161
162impl<C, I, O> KParseError<C, I> for Result<(I, O), nom::Err<ParserError<C, I>>>
163where
164 C: Code,
165 I: Clone + Debug + SpanFragment,
166 I: InputTake + InputLength + InputIter,
167{
168 type WrappedError = ParserError<C, I>;
169
170 fn from(code: C, span: I) -> Self {
171 Err(nom::Err::Error(KParseError::from(code, span)))
172 }
173
174 fn with_code(self, code: C) -> Self {
175 match self {
176 Ok((rest, token)) => Ok((rest, token)),
177 Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.with_code(code))),
178 Err(nom::Err::Failure(e)) => Err(nom::Err::Error(e.with_code(code))),
179 Err(nom::Err::Incomplete(e)) => Err(nom::Err::Incomplete(e)),
180 }
181 }
182
183 fn code(&self) -> Option<C> {
184 match self {
185 Ok(_) => None,
186 Err(nom::Err::Error(e)) => Some(e.code),
187 Err(nom::Err::Failure(e)) => Some(e.code),
188 Err(nom::Err::Incomplete(_)) => None,
189 }
190 }
191
192 fn span(&self) -> Option<I> {
193 match self {
194 Ok(_) => None,
195 Err(nom::Err::Error(e)) => Some(e.span.clone()),
196 Err(nom::Err::Failure(e)) => Some(e.span.clone()),
197 Err(nom::Err::Incomplete(_)) => None,
198 }
199 }
200
201 fn err(&self) -> Option<&Self::WrappedError> {
202 match self {
203 Ok(_) => None,
204 Err(nom::Err::Error(e)) => Some(e),
205 Err(nom::Err::Failure(e)) => Some(e),
206 Err(nom::Err::Incomplete(_)) => None,
207 }
208 }
209
210 fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
211 match self {
212 Ok(_) => None,
213 Err(nom::Err::Error(e)) => Some((e.code, e.span.clone(), e)),
214 Err(nom::Err::Failure(e)) => Some((e.code, e.span.clone(), e)),
215 Err(nom::Err::Incomplete(_)) => None,
216 }
217 }
218}
219
220pub trait AppendParserError<Rhs = Self> {
222 type Output;
225 fn append(&mut self, err: Rhs) -> Self::Output;
227}
228
229impl<C, I> AppendParserError<ParserError<C, I>> for ParserError<C, I>
230where
231 C: Code,
232 I: Clone,
233{
234 type Output = ();
235
236 fn append(&mut self, err: ParserError<C, I>) {
237 self.append_err(err);
238 }
239}
240
241impl<C, I> AppendParserError<ParserError<C, I>> for Option<ParserError<C, I>>
242where
243 C: Code,
244 I: Clone,
245{
246 type Output = ();
247
248 fn append(&mut self, err: ParserError<C, I>) {
249 match self {
250 None => *self = Some(err),
251 Some(self_err) => self_err.append_err(err),
252 }
253 }
254}
255
256impl<C, I> AppendParserError<nom::Err<ParserError<C, I>>> for Option<ParserError<C, I>>
257where
258 C: Code,
259 I: Clone,
260{
261 type Output = Result<(), nom::Err<ParserError<C, I>>>;
262
263 fn append(
264 &mut self,
265 err: nom::Err<ParserError<C, I>>,
266 ) -> Result<(), nom::Err<ParserError<C, I>>> {
267 match self {
268 None => match err {
269 nom::Err::Incomplete(e) => return Err(nom::Err::Incomplete(e)),
270 nom::Err::Error(e) => *self = Some(e),
271 nom::Err::Failure(e) => *self = Some(e),
272 },
273 Some(self_err) => match err {
274 nom::Err::Incomplete(e) => return Err(nom::Err::Incomplete(e)),
275 nom::Err::Error(e) => self_err.append_err(e),
276 nom::Err::Failure(e) => self_err.append_err(e),
277 },
278 };
279 Ok(())
280 }
281}
282
283impl<C, I> AppendParserError<ParserError<C, I>> for nom::Err<ParserError<C, I>>
284where
285 C: Code,
286 I: Clone,
287{
288 type Output = Result<(), nom::Err<ParserError<C, I>>>;
289
290 fn append(&mut self, err: ParserError<C, I>) -> Self::Output {
291 match self {
292 nom::Err::Incomplete(e) => return Err(nom::Err::Incomplete(*e)),
293 nom::Err::Error(e) => e.append_err(err),
294 nom::Err::Failure(e) => e.append_err(err),
295 }
296 Ok(())
297 }
298}
299
300impl<C, I> AppendParserError<nom::Err<ParserError<C, I>>> for ParserError<C, I>
301where
302 C: Code,
303 I: Clone,
304{
305 type Output = Result<(), nom::Err<ParserError<C, I>>>;
306
307 fn append(&mut self, err: nom::Err<ParserError<C, I>>) -> Self::Output {
308 match err {
309 nom::Err::Incomplete(e) => return Err(nom::Err::Incomplete(e)),
310 nom::Err::Error(e) => self.append_err(e),
311 nom::Err::Failure(e) => self.append_err(e),
312 }
313 Ok(())
314 }
315}
316
317impl<C, I> AppendParserError<nom::Err<ParserError<C, I>>> for nom::Err<ParserError<C, I>>
318where
319 C: Code,
320 I: Clone,
321{
322 type Output = Result<(), nom::Err<ParserError<C, I>>>;
323
324 fn append(&mut self, err: nom::Err<ParserError<C, I>>) -> Self::Output {
325 match self {
326 nom::Err::Incomplete(e) => return Err(nom::Err::Incomplete(*e)),
327 nom::Err::Error(e) | nom::Err::Failure(e) => match err {
328 nom::Err::Incomplete(_) => return Err(err),
329 nom::Err::Error(e2) | nom::Err::Failure(e2) => e.append_err(e2),
330 },
331 }
332 Ok(())
333 }
334}
335
336impl<C, I> nom::error::ParseError<I> for ParserError<C, I>
337where
338 C: Code,
339 I: Clone,
340{
341 fn from_error_kind(input: I, _kind: ErrorKind) -> Self {
342 ParserError {
343 code: C::NOM_ERROR,
344 span: input,
345 hints: Default::default(),
346 #[cfg(debug_assertions)]
347 backtrace: Backtrace::capture(),
348 }
349 }
350
351 fn append(_input: I, _kind: ErrorKind, other: Self) -> Self {
352 other
353 }
354
355 fn from_char(input: I, _ch: char) -> Self {
356 ParserError {
357 code: C::NOM_ERROR,
358 span: input,
359 hints: Default::default(),
360 #[cfg(debug_assertions)]
361 backtrace: Backtrace::capture(),
362 }
363 }
364
365 fn or(mut self, other: Self) -> Self {
367 self.append_err(other);
368 self
369 }
370}
371
372impl<C, I> Display for ParserError<C, I>
373where
374 C: Code,
375 I: Clone + Debug + SpanFragment,
376 I: InputTake + InputLength + InputIter,
377{
378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379 write!(f, "{}", self.code)?;
380
381 if self.iter_expected().next().is_some() {
382 write!(f, " expected ")?;
383 }
384 for (i, exp) in self.iter_expected().enumerate() {
385 if i > 0 {
386 write!(f, " ")?;
387 }
388 write!(f, "{}", exp.code)?;
389 }
390
391 if self.iter_suggested().next().is_some() {
392 write!(f, " suggested ")?;
393 }
394 for (i, sug) in self.iter_suggested().enumerate() {
395 if i > 0 {
396 write!(f, " ")?;
397 }
398 write!(f, "{}", sug.code)?;
399 }
400
401 if let Some(cause) = self.cause() {
402 write!(f, " cause {:0?}, ", cause)?;
403 }
404
405 write!(
407 f,
408 " for span {:?}",
409 restrict(DebugWidth::Short, self.span.clone()).fragment()
410 )?;
411 Ok(())
412 }
413}
414
415impl<C, I> Debug for ParserError<C, I>
416where
417 C: Code,
418 I: Clone + Debug + SpanFragment,
419 I: InputTake + InputLength + InputIter,
420{
421 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422 debug_parse_error(f, self)
423 }
424}
425
426impl<C, I> Debug for Hints<C, I>
427where
428 C: Code,
429 I: Clone + Debug + SpanFragment,
430 I: InputTake + InputLength + InputIter,
431{
432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
433 match self {
434 Hints::Expect(v) => write!(f, "Expect {:?} ", v),
435 Hints::Suggest(v) => write!(f, "Suggest {:?} ", v),
436 Hints::Cause(v) => write!(f, "Cause {:?}", v),
437 Hints::UserData(v) => write!(f, "UserData {:?}", v),
438 }
439 }
440}
441
442impl<C, I> Error for ParserError<C, I>
443where
444 C: Code,
445 I: Clone + Debug + SpanFragment,
446 I: InputTake + InputLength + InputIter,
447{
448 fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
449 self.hints
450 .iter()
451 .find(|v| matches!(v, Hints::Cause(_)))
452 .and_then(|v| {
453 if let Hints::Cause(e) = v {
454 Some(e.as_ref())
455 } else {
456 None
457 }
458 })
459 }
460}
461
462#[derive(Clone, Copy)]
464pub struct SpanAndCode<C, I> {
465 pub code: C,
467 pub span: I,
469}
470
471impl<C, I> Debug for SpanAndCode<C, I>
472where
473 C: Code,
474 I: Clone + Debug + SpanFragment,
475 I: InputTake + InputLength + InputIter,
476{
477 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478 let w = f.width().into();
479 write!(
480 f,
481 "{:?}:{:?}",
482 self.code,
483 restrict(w, self.span.clone()).fragment()
484 )?;
485 Ok(())
486 }
487}
488
489impl<C, I> ParserError<C, I>
490where
491 C: Code,
492 I: Clone,
493{
494 pub fn new(code: C, span: I) -> Self {
496 Self {
497 code,
498 span,
499 hints: Vec::new(),
500 #[cfg(debug_assertions)]
501 backtrace: Backtrace::capture(),
502 }
503 }
504
505 pub fn with_cause<E>(mut self, err: E) -> Self
507 where
508 E: Error + 'static,
509 {
510 self.hints.push(Hints::Cause(Box::new(err)));
511 self
512 }
513
514 pub fn with_user_data<Y>(mut self, user_data: Y) -> Self
516 where
517 Y: 'static,
518 {
519 self.hints.push(Hints::UserData(Box::new(user_data)));
520 self
521 }
522
523 pub fn cause(&self) -> Option<&dyn Error> {
525 self.hints
526 .iter()
527 .find(|v| matches!(v, Hints::Cause(_)))
528 .and_then(|v| match v {
529 Hints::Cause(e) => Some(e.as_ref()),
530 _ => None,
531 })
532 }
533
534 pub fn user_data<Y: 'static>(&self) -> Option<&Y> {
536 self.hints
537 .iter()
538 .find(|v| matches!(v, Hints::UserData(_)))
539 .and_then(|v| match v {
540 Hints::UserData(e) => e.downcast_ref::<Y>(),
541 _ => None,
542 })
543 }
544
545 pub fn error(self) -> nom::Err<Self> {
547 nom::Err::Error(self)
548 }
549
550 pub fn failure(self) -> nom::Err<Self> {
552 nom::Err::Failure(self)
553 }
554
555 pub fn append_err(&mut self, other: ParserError<C, I>) {
560 if other.code != C::NOM_ERROR {
561 self.expect(other.code, other.span);
562 }
563 for hint in other.hints {
564 self.hints.push(hint);
565 }
566 }
567
568 pub fn with_code(mut self, code: C) -> Self {
571 if self.code != code && self.code != C::NOM_ERROR {
572 self.hints.push(Hints::Expect(SpanAndCode {
573 code: self.code,
574 span: self.span.clone(),
575 }));
576 }
577 self.code = code;
578 self
579 }
580
581 pub fn is_expected(&self, code: C) -> bool {
584 if self.code == code {
585 return true;
586 }
587 for exp in &self.hints {
588 if let Hints::Expect(v) = exp {
589 if v.code == code {
590 return true;
591 }
592 }
593 }
594 false
595 }
596
597 pub fn expect(&mut self, code: C, span: I) {
599 self.hints.push(Hints::Expect(SpanAndCode { code, span }))
600 }
601
602 pub fn append_expected(&mut self, exp_iter: impl Iterator<Item = SpanAndCode<C, I>>) {
604 for exp in exp_iter {
605 self.hints.push(Hints::Expect(exp));
606 }
607 }
608
609 pub fn iter_expected(&self) -> impl Iterator<Item = SpanAndCode<C, I>> + '_ {
615 self.hints.iter().rev().filter_map(|v| match v {
616 Hints::Expect(v) => Some(v.clone()),
617 _ => None,
618 })
619 }
620
621 pub fn suggest(&mut self, code: C, span: I) {
623 self.hints.push(Hints::Suggest(SpanAndCode { code, span }))
624 }
625
626 pub fn is_suggested(&self, code: C) -> bool {
629 for exp in &self.hints {
630 if let Hints::Suggest(v) = exp {
631 if v.code == code {
632 return true;
633 }
634 }
635 }
636 false
637 }
638
639 pub fn append_suggested(&mut self, sug_iter: impl Iterator<Item = SpanAndCode<C, I>>) {
641 for exp in sug_iter {
642 self.hints.push(Hints::Suggest(exp));
643 }
644 }
645
646 pub fn iter_suggested(&self) -> impl Iterator<Item = SpanAndCode<C, I>> + '_ {
648 self.hints.iter().rev().filter_map(|v| match v {
649 Hints::Suggest(v) => Some(v.clone()),
650 _ => None,
651 })
652 }
653}