1use std::fmt::{Display, Formatter};
2use serde::Serialize;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Hash)]
5pub struct Span {
6 pub start: usize,
7 pub end: usize,
8 pub start_position: (usize, usize),
9 pub end_position: (usize, usize),
10}
11
12impl Default for Span {
13
14 fn default() -> Self {
15 Self {
16 start: 0,
17 end: 0,
18 start_position: (1, 1),
19 end_position: (1, 1),
20 }
21 }
22}
23
24impl Span {
25
26 pub fn contains(&self, position: usize) -> bool {
27 position >= self.start && position <= self.end
28 }
29
30 pub fn contains_line_col(&self, line_col: (usize, usize)) -> bool {
31 line_col.0 >= self.start_position.0 &&
32 line_col.0 <= self.end_position.0 &&
33 if line_col.0 == self.start_position.0 { line_col.1 >= self.start_position.1 } else { true } &&
34 if line_col.0 == self.end_position.0 { line_col.1 <= self.end_position.1 } else { true }
35 }
36
37 pub fn overlaps(&self, other: Span) -> bool {
38 self.contains(other.start) || self.contains(other.end)
39 }
40
41 pub fn merge(&self, other: &Span) -> Span {
42 Span {
43 start: if self.start < other.start { self.start } else { other.start },
44 end: if self.end < other.end { other.end } else { self.end },
45 start_position: if self.start < other.start { self.start_position } else { other.start_position },
46 end_position: if self.end < other.end { other.end_position } else { self.end_position },
47 }
48 }
49}
50
51impl Display for Span {
52
53 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54 f.write_str(&format!(
55 "{}:{} - {}:{}",
56 self.start_position.0,
57 self.start_position.1,
58 self.end_position.0,
59 self.end_position.1
60 ))
61 }
62}