source_cache/text/
display.rs1use super::*;
2
3impl Debug for SourceSpan {
4 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
5 f.debug_struct("FileSpan").field("start", &self.start).field("end", &self.end).field("file", &self.file).finish()
6 }
7}
8
9impl Display for SourceSpan {
10 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
11 write!(f, "FileSpan(0x{:X}, {}..{})", self.file.hash, self.start, self.end)
12 }
13}
14
15impl<S: Into<String>> From<S> for SourceText {
16 fn from(source: S) -> Self {
20 let text = source.into();
21 let mut offset = 0;
22 let mut last_line: Option<(SourceLine, bool)> = None;
24 let mut lines: Vec<SourceLine> = text
25 .split_inclusive([
26 '\r', '\n', '\x0B', '\x0C', '\u{0085}', '\u{2028}', '\u{2029}', ])
34 .flat_map(|line| {
35 if let Some((last, ends_with_cr)) = last_line.as_mut() {
39 if *ends_with_cr && line == "\n" {
40 last.length += 1;
41 offset += 1;
42 return core::mem::replace(&mut last_line, None).map(|(l, _)| l);
43 }
44 }
45
46 let len = line.len();
47 let ends_with_cr = line.ends_with('\r');
48 let line = SourceLine { offset, length: len as u32, text: line.trim_end().to_owned() };
49 offset += line.length;
50 core::mem::replace(&mut last_line, Some((line, ends_with_cr))).map(|(l, _)| l)
51 })
52 .collect();
53
54 if let Some((l, _)) = last_line {
55 lines.push(l);
56 }
57
58 Self { path: SourcePath::Anonymous, raw: text, lines, length: offset, dirty: false }
59 }
60}