1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
5pub struct Span {
6 pub start: usize,
7 pub end: usize,
8}
9
10impl Span {
11 pub fn new(start: usize, end: usize) -> Self {
12 Self { start, end }
13 }
14
15 pub fn range(&self) -> std::ops::Range<usize> {
16 self.start..self.end
17 }
18
19 pub fn merge(self, other: Span) -> Span {
21 Span {
22 start: self.start.min(other.start),
23 end: self.end.max(other.end),
24 }
25 }
26}
27
28impl From<std::ops::Range<usize>> for Span {
29 fn from(r: std::ops::Range<usize>) -> Self {
30 Span {
31 start: r.start,
32 end: r.end,
33 }
34 }
35}
36
37pub fn line_col(source: &str, offset: usize) -> (usize, usize) {
42 let mut line = 1;
43 let mut col = 1;
44 for (i, ch) in source.char_indices() {
45 if i >= offset {
46 break;
47 }
48 if ch == '\n' {
49 line += 1;
50 col = 1;
51 } else {
52 col += 1;
53 }
54 }
55 (line, col)
56}