difftreelog
feat add original offset to location
in: master
1 file changed
crates/jrsonnet-evaluator/src/trace/location.rsdiffbeforeafterboth1#[derive(Clone, PartialEq, Debug)]2pub struct CodeLocation {3 pub line: usize,4 pub column: usize,56 pub line_start_offset: usize,7 pub line_end_offset: usize,8}910pub fn offset_to_location(file: &str, offsets: &[usize]) -> Vec<CodeLocation> {11 if offsets.is_empty() {12 return vec![];13 }14 let mut line = 1;15 let mut column = 1;16 let max_offset = *offsets.iter().max().unwrap();1718 let mut offset_map = offsets19 .iter()20 .enumerate()21 .map(|(pos, offset)| (*offset, pos))22 .collect::<Vec<_>>();23 offset_map.sort_by_key(|v| v.0);24 offset_map.reverse();2526 let mut out = vec![27 CodeLocation {28 column: 0,29 line: 0,30 line_start_offset: 0,31 line_end_offset: 032 };33 offsets.len()34 ];35 let mut with_no_known_line_ending = vec![];36 let mut this_line_offset = 0;37 for (pos, ch) in file.chars().enumerate() {38 column += 1;39 match offset_map.last() {40 Some(x) if x.0 == pos => {41 let out_idx = x.1;42 with_no_known_line_ending.push(out_idx);43 out[out_idx].line = line;44 out[out_idx].column = column;45 out[out_idx].line_start_offset = this_line_offset;46 offset_map.pop();47 }48 _ => {}49 }50 if ch == '\n' {51 line += 1;52 column = 1;5354 for idx in with_no_known_line_ending.drain(..) {55 out[idx].line_end_offset = pos;56 }57 this_line_offset = pos + 1;5859 if pos == max_offset + 1 {60 break;61 }62 }63 }64 let file_end = file.chars().count();65 for idx in with_no_known_line_ending {66 out[idx].line_end_offset = file_end;67 }6869 out70}7172#[cfg(test)]73pub mod tests {74 use super::{offset_to_location, CodeLocation};7576 #[test]77 fn test() {78 assert_eq!(79 offset_to_location(80 "hello world\n_______________________________________________________",81 &[0, 14]82 ),83 vec![84 CodeLocation {85 line: 1,86 column: 2,87 line_start_offset: 0,88 line_end_offset: 1189 },90 CodeLocation {91 line: 2,92 column: 4,93 line_start_offset: 12,94 line_end_offset: 6795 }96 ]97 )98 }99}1#[derive(Clone, PartialEq, Debug)]2pub struct CodeLocation {3 pub offset: usize,45 pub line: usize,6 pub column: usize,78 pub line_start_offset: usize,9 pub line_end_offset: usize,10}1112pub fn offset_to_location(file: &str, offsets: &[usize]) -> Vec<CodeLocation> {13 if offsets.is_empty() {14 return vec![];15 }16 let mut line = 1;17 let mut column = 1;18 let max_offset = *offsets.iter().max().unwrap();1920 let mut offset_map = offsets21 .iter()22 .enumerate()23 .map(|(pos, offset)| (*offset, pos))24 .collect::<Vec<_>>();25 offset_map.sort_by_key(|v| v.0);26 offset_map.reverse();2728 let mut out = vec![29 CodeLocation {30 offset: 0,31 column: 0,32 line: 0,33 line_start_offset: 0,34 line_end_offset: 035 };36 offsets.len()37 ];38 let mut with_no_known_line_ending = vec![];39 let mut this_line_offset = 0;40 for (pos, ch) in file.chars().enumerate() {41 column += 1;42 match offset_map.last() {43 Some(x) if x.0 == pos => {44 let out_idx = x.1;45 with_no_known_line_ending.push(out_idx);46 out[out_idx].offset = pos;47 out[out_idx].line = line;48 out[out_idx].column = column;49 out[out_idx].line_start_offset = this_line_offset;50 offset_map.pop();51 }52 _ => {}53 }54 if ch == '\n' {55 line += 1;56 column = 1;5758 for idx in with_no_known_line_ending.drain(..) {59 out[idx].line_end_offset = pos;60 }61 this_line_offset = pos + 1;6263 if pos == max_offset + 1 {64 break;65 }66 }67 }68 let file_end = file.chars().count();69 for idx in with_no_known_line_ending {70 out[idx].line_end_offset = file_end;71 }7273 out74}7576#[cfg(test)]77pub mod tests {78 use super::{offset_to_location, CodeLocation};7980 #[test]81 fn test() {82 assert_eq!(83 offset_to_location(84 "hello world\n_______________________________________________________",85 &[0, 14]86 ),87 vec![88 CodeLocation {89 offset: 0,90 line: 1,91 column: 2,92 line_start_offset: 0,93 line_end_offset: 11,94 },95 CodeLocation {96 offset: 14,97 line: 2,98 column: 4,99 line_start_offset: 12,100 line_end_offset: 67101 }102 ]103 )104 }105}