1#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4pub struct Loc {
5 pub line: u32,
6 pub col: u32,
7 pub byte: usize,
8}
9
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
12pub struct Span {
13 pub start: Loc,
14 pub end: Loc,
15}
16
17impl Span {
18 pub(crate) fn new(start: Loc, end: Loc) -> Self {
19 Span { start, end }
20 }
21
22 pub fn unite(self, other: Span) -> Span {
24 let dummy = Span::default();
25 if self == dummy {
26 return other;
27 }
28 if other == dummy {
29 return self;
30 }
31 let start = if self.start.byte <= other.start.byte {
32 self.start
33 } else {
34 other.start
35 };
36 let end = if self.end.byte >= other.end.byte {
37 self.end
38 } else {
39 other.end
40 };
41 Span { start, end }
42 }
43}
44
45impl syan::span::Span for Span {
46 fn migrate(self, other: Self) -> Self {
47 self.unite(other)
48 }
49}
50
51impl std::fmt::Display for Span {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 if self.start.line == self.end.line {
54 write!(
55 f,
56 "line {}, characters {}-{}",
57 self.start.line, self.start.col, self.end.col
58 )
59 } else {
60 write!(
61 f,
62 "line {}, character {} to line {}, character {}",
63 self.start.line, self.start.col, self.end.line, self.end.col
64 )
65 }
66 }
67}