Skip to content

Commit 163f087

Browse files
committed
refactor: map offset to location
1 parent 87198f9 commit 163f087

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

src/package_json/simd.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
};
99

1010
use self_cell::self_cell;
11-
use simd_json::{borrowed::Value, prelude::*};
11+
use simd_json::{borrowed::Value, prelude::*, to_borrowed_value};
1212

1313
use crate::{path::PathUtil, JSONError, ResolveError};
1414

@@ -78,15 +78,17 @@ impl PackageJson {
7878
let json_cell = JSONCell::try_new(json, |v| {
7979
// SAFETY: We have exclusive ownership of the Vec<u8>, so it's safe to cast to mutable.
8080
let slice = unsafe { std::slice::from_raw_parts_mut(v.as_ptr().cast_mut(), v.len()) };
81-
simd_json::value::borrowed::to_value(slice)
82-
})
83-
.map_err(|parse_error| {
84-
ResolveError::JSON(JSONError {
85-
path: path.clone(),
86-
message: "sj parse failed".to_string(),
87-
line: parse_error.index(),
88-
column: parse_error.index(),
89-
content: None,
81+
82+
to_borrowed_value(slice).map_err(|e| {
83+
let content = String::from_utf8_lossy(v);
84+
let (line, column) = offset_to_location(&content, e.index());
85+
ResolveError::JSON(JSONError {
86+
path: path.clone(),
87+
message: format!("JSON parse error: {:?}", e.error()),
88+
line,
89+
column,
90+
content: Some(content.to_string()),
91+
})
9092
})
9193
})?;
9294

@@ -300,6 +302,28 @@ impl PackageJson {
300302
}
301303
}
302304

305+
fn offset_to_location(json: &str, offset: usize) -> (usize, usize) {
306+
let mut line = 0;
307+
let mut col = 0;
308+
let mut current_offset = 0;
309+
for ch in json.chars() {
310+
let b = ch.len_utf8();
311+
current_offset += b;
312+
if ch == '\n' {
313+
line += 1;
314+
col = 0;
315+
} else {
316+
col += b;
317+
}
318+
319+
if current_offset >= offset {
320+
break;
321+
}
322+
}
323+
// zero-based to one-based
324+
(line + 1, col + 1)
325+
}
326+
303327
impl<'a> TryFrom<&'a JSONValue<'a>> for SideEffects {
304328
type Error = &'static str;
305329
fn try_from(value: &'a JSONValue<'a>) -> Result<Self, Self::Error> {

0 commit comments

Comments
 (0)