From 68375371a5fde6ee14f190c14e9a9cee0697f022 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 28 Feb 2024 16:34:00 +0000 Subject: [PATCH] Attempted to fix labelling, added labelling test --- src/error.rs | 20 +++++++++++++++++++- src/label.rs | 2 +- src/lib.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/error.rs b/src/error.rs index 7db01c7f..6892229b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -426,6 +426,7 @@ impl<'a, T, L> RichReason<'a, T, L> { mut fmt_span: impl FnMut(&S, &mut fmt::Formatter<'_>) -> fmt::Result, mut fmt_label: impl FnMut(&L, &mut fmt::Formatter<'_>) -> fmt::Result, span: Option<&S>, + #[cfg(feature = "label")] context: &[(L, S)], ) -> fmt::Result { match self { RichReason::ExpectedFound { expected, found } => { @@ -467,6 +468,13 @@ impl<'a, T, L> RichReason<'a, T, L> { } } } + #[cfg(feature = "label")] + for (l, s) in context { + write!(f, " in ")?; + fmt_label(l, f)?; + write!(f, " at ")?; + fmt_span(s, f)?; + } Ok(()) } } @@ -526,7 +534,15 @@ where L: fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner_fmt(f, T::fmt, |_: &(), _| Ok(()), L::fmt, None) + self.inner_fmt( + f, + T::fmt, + |_: &(), _| Ok(()), + L::fmt, + None, + #[cfg(feature = "label")] + &[], + ) } } @@ -557,6 +573,8 @@ impl<'a, T, S, L> Rich<'a, T, S, L> { fmt_span, fmt_label, if with_spans { Some(&self.span) } else { None }, + #[cfg(feature = "label")] + &self.context, ) } } diff --git a/src/label.rs b/src/label.rs index d0879bfc..4ba4d351 100644 --- a/src/label.rs +++ b/src/label.rs @@ -57,7 +57,7 @@ where inp.errors.alt = old_alt; if let Some(mut new_alt) = new_alt { - let before_next = before.offset.into() + 1; + let before_next = before.offset.into(); if new_alt.pos.into() == before_next { new_alt.err.label_with(self.label.clone()); } else if self.is_context && new_alt.pos.into() > before_next { diff --git a/src/lib.rs b/src/lib.rs index 8abbe30a..8ebb8bf5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3518,4 +3518,30 @@ mod tests { todo().map_with(|expr, e| (expr, e.span())) } } + + #[cfg(feature = "label")] + #[test] + fn label() { + use crate::label::LabelError; + + fn parser<'src>() -> impl Parser<'src, &'src str, (), extra::Err>> { + just("hello").labelled("greeting").as_context().ignored() + } + + let mut err = as crate::Error<&str>>::expected_found( + Some(Some('h'.into())), + Some('g'.into()), + (0..1).into(), + ); + as LabelError<&str, _>>::label_with(&mut err, "greeting"); + assert_eq!(parser().parse("goodbye").into_errors(), vec![err]); + + let mut err = as crate::Error<&str>>::expected_found( + Some(Some('l'.into())), + Some('p'.into()), + (3..4).into(), + ); + as LabelError<&str, _>>::in_context(&mut err, "greeting", (0..3).into()); + assert_eq!(parser().parse("help").into_errors(), vec![err]); + } }