From 7cf53ec23c4ebaa0af00b7ee58b846105aaf8e12 Mon Sep 17 00:00:00 2001 From: Zane Duffield Date: Thu, 19 Dec 2024 16:21:43 +0800 Subject: [PATCH] feat(path): Show location in parse error messages --- src/path/mod.rs | 2 +- src/path/parser.rs | 60 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/path/mod.rs b/src/path/mod.rs index 3c0b4213..aaa55b12 100644 --- a/src/path/mod.rs +++ b/src/path/mod.rs @@ -27,7 +27,7 @@ impl FromStr for Expression { struct ParseError(String); impl ParseError { - fn new(inner: winnow::error::ContextError) -> Self { + fn new(inner: winnow::error::ParseError<&str, winnow::error::ContextError>) -> Self { Self(inner.to_string()) } } diff --git a/src/path/parser.rs b/src/path/parser.rs index 5bbd266f..dcd0f284 100644 --- a/src/path/parser.rs +++ b/src/path/parser.rs @@ -9,6 +9,7 @@ use winnow::combinator::opt; use winnow::combinator::repeat; use winnow::combinator::seq; use winnow::error::ContextError; +use winnow::error::ParseError; use winnow::error::StrContext; use winnow::error::StrContextValue; use winnow::prelude::*; @@ -17,9 +18,8 @@ use winnow::token::take_while; use crate::path::Expression; -pub(crate) fn from_str(mut input: &str) -> Result { - let input = &mut input; - path.parse(input).map_err(|e| e.into_inner()) +pub(crate) fn from_str(input: &str) -> Result> { + path.parse(input) } fn path(i: &mut &str) -> PResult { @@ -93,6 +93,8 @@ fn integer(i: &mut &str) -> PResult { #[cfg(test)] mod test { + use snapbox::{assert_data_eq, str}; + use super::Expression::*; use super::*; @@ -143,36 +145,70 @@ mod test { #[test] fn test_invalid_identifier() { let err = from_str("!").unwrap_err(); - assert_eq!( - "invalid identifier\nexpected ASCII alphanumeric, `_`, `-`", - err.to_string() + assert_data_eq!( + err.to_string(), + str![[r#" +! +^ +invalid identifier +expected ASCII alphanumeric, `_`, `-` +"#]] ); } #[test] fn test_invalid_child() { let err = from_str("a..").unwrap_err(); - assert_eq!( - "invalid identifier\nexpected ASCII alphanumeric, `_`, `-`", - err.to_string() + assert_data_eq!( + err.to_string(), + str![[r#" +a.. + ^ +invalid identifier +expected ASCII alphanumeric, `_`, `-` +"#]] ); } #[test] fn test_invalid_subscript() { let err = from_str("a[b]").unwrap_err(); - assert_eq!("invalid subscript\nexpected integer", err.to_string()); + assert_data_eq!( + err.to_string(), + str![[r#" +a[b] + ^ +invalid subscript +expected integer +"#]] + ); } #[test] fn test_incomplete_subscript() { let err = from_str("a[0").unwrap_err(); - assert_eq!("invalid subscript\nexpected `]`", err.to_string()); + assert_data_eq!( + err.to_string(), + str![[r#" +a[0 + ^ +invalid subscript +expected `]` +"#]] + ); } #[test] fn test_invalid_postfix() { let err = from_str("a!b").unwrap_err(); - assert_eq!("invalid postfix\nexpected `[`, `.`", err.to_string()); + assert_data_eq!( + err.to_string(), + str![[r#" +a!b + ^ +invalid postfix +expected `[`, `.` +"#]] + ); } }