emmylua_parser/text/
text_range.rs1use rowan::TextRange;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct SourceRange {
5 pub start_offset: usize,
6 pub length: usize,
7}
8
9impl SourceRange {
10 pub fn new(start_offset: usize, length: usize) -> SourceRange {
11 SourceRange {
12 start_offset,
13 length,
14 }
15 }
16
17 pub fn from_start_end(start_offset: usize, end_offset: usize) -> Self {
18 assert!(start_offset <= end_offset);
19 Self::new(start_offset, end_offset - start_offset)
20 }
21
22 pub const EMPTY: SourceRange = SourceRange {
23 start_offset: 0,
24 length: 0,
25 };
26
27 pub fn end_offset(&self) -> usize {
28 self.start_offset + self.length
29 }
30
31 pub fn contains(&self, offset: usize) -> bool {
32 offset >= self.start_offset && offset < self.end_offset()
33 }
34
35 pub fn contains_inclusive(&self, offset: usize) -> bool {
36 offset >= self.start_offset && offset <= self.end_offset()
37 }
38
39 pub fn contain_range(&self, range: &SourceRange) -> bool {
40 range.start_offset >= self.start_offset && range.end_offset() <= self.end_offset()
41 }
42
43 pub fn intersect(&self, range: &SourceRange) -> bool {
44 self.start_offset < range.end_offset() && range.start_offset < self.end_offset()
45 }
46
47 pub fn moved(&self, offset: usize) -> SourceRange {
48 debug_assert!(offset <= self.length);
49 SourceRange::new(self.start_offset + offset, self.length - offset)
50 }
51
52 pub fn merge(&self, range: &SourceRange) -> SourceRange {
53 let start = self.start_offset.min(range.start_offset);
54 let end = self.end_offset().max(range.end_offset());
55 SourceRange {
56 start_offset: start,
57 length: end - start,
58 }
59 }
60
61 pub fn is_empty(&self) -> bool {
62 self.length == 0
63 }
64}
65
66impl std::fmt::Display for SourceRange {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "[{}, {})", self.start_offset, self.end_offset())
69 }
70}
71
72impl From<SourceRange> for TextRange {
73 fn from(val: SourceRange) -> Self {
74 TextRange::new(
75 (val.start_offset as u32).into(),
76 (val.end_offset() as u32).into(),
77 )
78 }
79}
80
81impl From<TextRange> for SourceRange {
82 fn from(val: TextRange) -> Self {
83 SourceRange::new(val.start().into(), val.len().into())
84 }
85}