use super::*;
impl Debug for SourceSpan {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FileSpan").field("start", &self.start).field("end", &self.end).field("file", &self.file).finish()
}
}
impl Display for SourceSpan {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "FileSpan(0x{:X}, {}..{})", self.file.hash, self.start, self.end)
}
}
impl<S: Into<String>> From<S> for SourceText {
fn from(source: S) -> Self {
let text = source.into();
let mut offset = 0;
let mut last_line: Option<(SourceLine, bool)> = None;
let mut lines: Vec<SourceLine> = text
.split_inclusive([
'\r', '\n', '\x0B', '\x0C', '\u{0085}', '\u{2028}', '\u{2029}', ])
.flat_map(|line| {
if let Some((last, ends_with_cr)) = last_line.as_mut() {
if *ends_with_cr && line == "\n" {
last.length += 1;
offset += 1;
return core::mem::replace(&mut last_line, None).map(|(l, _)| l);
}
}
let len = line.len();
let ends_with_cr = line.ends_with('\r');
let line = SourceLine { offset, length: len as u32, text: line.trim_end().to_owned() };
offset += line.length;
core::mem::replace(&mut last_line, Some((line, ends_with_cr))).map(|(l, _)| l)
})
.collect();
if let Some((l, _)) = last_line {
lines.push(l);
}
Self { path: SourcePath::Anonymous, raw: text, lines, length: offset, dirty: false }
}
}