diff --git a/Cargo.lock b/Cargo.lock index 6f0b1514..b0ad29a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1428,6 +1428,7 @@ dependencies = [ "fs4", "home", "indexmap", + "line-index", "log", "petgraph", "schemars", diff --git a/crates/moonbuild/src/expect.rs b/crates/moonbuild/src/expect.rs index 19e268f5..0e7a6271 100644 --- a/crates/moonbuild/src/expect.rs +++ b/crates/moonbuild/src/expect.rs @@ -18,6 +18,7 @@ use anyhow::Context; use colored::Colorize; +use moonutil::common::line_col_to_byte_idx; use std::collections::BTreeSet; use std::collections::HashMap; use std::path::PathBuf; @@ -217,14 +218,6 @@ impl Replace { } } -fn line_col_to_byte_idx(line_index: &line_index::LineIndex, line: u32, col: u32) -> Option { - let offset = line_index.offset(line_index.to_utf8( - line_index::WideEncoding::Utf32, - line_index::WideLineCol { line, col }, - )?)?; - Some(usize::from(offset)) -} - fn parse_expect_failed_message(msg: &str) -> anyhow::Result { let j: ExpectFailedRaw = serde_json_lenient::from_str(msg) .context(format!("parse expect test result failed: {}", msg))?; diff --git a/crates/moonutil/Cargo.toml b/crates/moonutil/Cargo.toml index ac6c9d4f..ac956855 100644 --- a/crates/moonutil/Cargo.toml +++ b/crates/moonutil/Cargo.toml @@ -44,6 +44,7 @@ env_logger.workspace = true log.workspace = true thiserror.workspace = true schemars.workspace = true +line-index.workspace = true [dev-dependencies] expect-test.workspace = true diff --git a/crates/moonutil/src/common.rs b/crates/moonutil/src/common.rs index 6f7aba9d..0006ec73 100644 --- a/crates/moonutil/src/common.rs +++ b/crates/moonutil/src/common.rs @@ -785,3 +785,15 @@ impl MooncGenTestInfo { result } } + +pub fn line_col_to_byte_idx( + line_index: &line_index::LineIndex, + line: u32, + col: u32, +) -> Option { + let offset = line_index.offset(line_index.to_utf8( + line_index::WideEncoding::Utf32, + line_index::WideLineCol { line, col }, + )?)?; + Some(usize::from(offset)) +} diff --git a/crates/moonutil/src/render.rs b/crates/moonutil/src/render.rs index 2748358f..a16af257 100644 --- a/crates/moonutil/src/render.rs +++ b/crates/moonutil/src/render.rs @@ -19,6 +19,8 @@ use ariadne::Fmt; use serde::{Deserialize, Serialize}; +use crate::common::line_col_to_byte_idx; + #[derive(Debug, Serialize, Deserialize)] pub struct MooncDiagnostic { pub level: String, @@ -43,24 +45,16 @@ pub struct Position { impl Position { pub fn calculate_offset(&self, content: &str) -> usize { - // line and col count from 1 - let mut current_line = 1; - let mut current_col = 1; - - for (char_idx, (_, c)) in content.char_indices().enumerate() { - if current_line == self.line && current_col == self.col { - return char_idx; - } - - if c == '\n' { - current_line += 1; - current_col = 1; - } else { - current_col += 1; - } - } + let line_index = line_index::LineIndex::new(content); + let byte_based_index = + line_col_to_byte_idx(&line_index, self.line as u32 - 1, self.col as u32 - 1).unwrap(); - content.chars().count() + content + .char_indices() + .enumerate() + .find(|(_, (byte_offset, _))| *byte_offset == byte_based_index) + .map(|(i, _)| i) + .unwrap_or(usize::from(line_index.len())) } }