From b17c1b6bcc49fdfb530e3c25316bbfdfa4e67a11 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 18 Apr 2024 16:38:51 -0500 Subject: [PATCH] fix(parser): Return correct span for multi-byte characters This is a step towards addressing rust-lang/cargo#13772 --- crates/toml_edit/src/error.rs | 18 +++++++++++------- crates/toml_edit/tests/testsuite/invalid.rs | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/toml_edit/src/error.rs b/crates/toml_edit/src/error.rs index d9630fca..6a278024 100644 --- a/crates/toml_edit/src/error.rs +++ b/crates/toml_edit/src/error.rs @@ -21,19 +21,23 @@ impl TomlError { ) -> Self { use winnow::stream::Stream; + let message = error.inner().to_string(); + let raw = raw.finish(); + let raw = String::from_utf8(raw.to_owned()).expect("original document was utf8"); + let offset = error.offset(); - let span = if offset == raw.len() { - offset..offset + let mut indices = raw[offset..].char_indices(); + indices.next(); + let len = if let Some((index, _)) = indices.next() { + index } else { - offset..(offset + 1) + raw.len() }; - - let message = error.inner().to_string(); - let raw = raw.finish(); + let span = offset..(offset + len); Self { message, - raw: Some(String::from_utf8(raw.to_owned()).expect("original document was utf8")), + raw: Some(raw), keys: Vec::new(), span: Some(span), } diff --git a/crates/toml_edit/tests/testsuite/invalid.rs b/crates/toml_edit/tests/testsuite/invalid.rs index a156792e..79724163 100644 --- a/crates/toml_edit/tests/testsuite/invalid.rs +++ b/crates/toml_edit/tests/testsuite/invalid.rs @@ -211,10 +211,10 @@ dotted key `k1` attempted to extend non-table type (integer) } #[test] -#[should_panic] fn emoji_error_span() { let input = "😀"; let err = input.parse::().unwrap_err(); dbg!(err.span()); - let _ = &input[err.span().unwrap()]; + let actual = &input[err.span().unwrap()]; + assert_eq!(actual, input); }