#[derive(Debug)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
pub fn new(start: usize, end: usize) -> Self {
assert!(start < end, "Span start must be less than end");
Span { start, end }
}
}
pub fn location_to_line_col(source: &str, index: usize) -> (usize, usize) {
let mut line = 1;
let mut col = 1;
for (i, c) in source.char_indices() {
if i == index {
break;
}
if c == '\n' {
line += 1;
col = 1;
} else {
col += 1;
}
}
(line, col)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_span_new() {
let span = Span::new(5, 10);
assert_eq!(span.start, 5);
assert_eq!(span.end, 10);
}
#[test]
#[should_panic(expected = "Span start must be less than end")]
fn test_span_new_invalid() {
Span::new(10, 5);
}
#[test]
fn test_location_to_line_col() {
let source = "Hello\nWorld";
assert_eq!(location_to_line_col(source, 0), (1, 1)); assert_eq!(location_to_line_col(source, 4), (1, 5)); assert_eq!(location_to_line_col(source, 5), (1, 6)); assert_eq!(location_to_line_col(source, 6), (2, 1)); assert_eq!(location_to_line_col(source, 10), (2, 5)); }
}