language_reporting/
simple.rs1#[derive(Debug, Clone)]
2pub struct SimpleFile {
3 name: String,
4 contents: String,
5}
6
7#[derive(Debug, Clone, Default)]
8pub struct SimpleReportingFiles {
9 files: Vec<SimpleFile>,
10}
11
12impl SimpleReportingFiles {
13 pub fn add(&mut self, name: impl Into<String>, value: impl Into<String>) -> usize {
14 self.files.push(SimpleFile {
15 name: name.into(),
16 contents: value.into(),
17 });
18
19 self.files.len() - 1
20 }
21}
22
23impl crate::ReportingFiles for SimpleReportingFiles {
24 type Span = SimpleSpan;
25 type FileId = usize;
26
27 fn file_id(&self, span: SimpleSpan) -> usize {
28 span.file_id
29 }
30
31 fn file_name(&self, id: usize) -> crate::FileName {
32 crate::FileName::Verbatim(self.files[id].name.clone())
33 }
34
35 fn byte_span(&self, _file: usize, _from_index: usize, _to_index: usize) -> Option<Self::Span> {
36 unimplemented!()
37 }
38
39 fn byte_index(&self, file: usize, line: usize, column: usize) -> Option<usize> {
40 let source = &self.files[file].contents;
41 let mut seen_lines = 0;
42 let mut seen_bytes = 0;
43
44 for (pos, _) in source.match_indices('\n') {
45 if seen_lines == line {
46 return Some(seen_bytes + column);
47 } else {
48 seen_lines += 1;
49 seen_bytes = pos + 1;
50 }
51 }
52
53 None
54 }
55
56 fn location(&self, file: usize, index: usize) -> Option<crate::Location> {
57 let source = &self.files[file].contents;
58 let mut seen_lines = 0;
59 let mut seen_bytes = 0;
60
61 for (pos, _) in source.match_indices('\n') {
62 if pos > index {
63 return Some(crate::Location::new(seen_lines, index - seen_bytes));
64 } else {
65 seen_lines += 1;
66 seen_bytes = pos;
67 }
68 }
69
70 None
71 }
72
73 fn line_span(&self, file: usize, line: usize) -> Option<Self::Span> {
74 let source = &self.files[file].contents;
75 let mut seen_lines = 0;
76 let mut seen_bytes = 0;
77
78 for (pos, _) in source.match_indices('\n') {
79 if seen_lines == line {
80 return Some(SimpleSpan::new(file, seen_bytes, pos));
81 } else {
82 seen_lines += 1;
83 seen_bytes = pos + 1;
84 }
85 }
86
87 None
88 }
89
90 fn source(&self, span: SimpleSpan) -> Option<String> {
91 let source = &self.files[span.file_id].contents;
92
93 Some(source[span.start..span.end].to_string())
94 }
95}
96
97#[derive(Debug, Copy, Clone)]
98pub struct SimpleSpan {
99 file_id: usize,
100 start: usize,
101 end: usize,
102}
103
104impl SimpleSpan {
105 pub fn new(file_id: usize, start: usize, end: usize) -> SimpleSpan {
106 assert!(
107 end >= start,
108 "SimpleSpan {} must be bigger than {}",
109 end,
110 start
111 );
112
113 SimpleSpan {
114 file_id,
115 start,
116 end,
117 }
118 }
119}
120
121impl crate::ReportingSpan for SimpleSpan {
122 fn with_start(&self, start: usize) -> Self {
123 SimpleSpan::new(self.file_id, start, self.end)
124 }
125
126 fn with_end(&self, end: usize) -> Self {
127 SimpleSpan::new(self.file_id, self.start, end)
128 }
129
130 fn start(&self) -> usize {
131 self.start
132 }
133
134 fn end(&self) -> usize {
135 self.end
136 }
137}