use std::fmt;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct Span {
pub file: Option<PathBuf>,
pub line_start: usize,
pub line_end: usize,
pub col_start: usize,
pub col_end: usize,
}
impl Span {
pub fn new(file: Option<PathBuf>, line: usize, col_start: usize, col_end: usize) -> Self {
Self { file, line_start: line, line_end: line, col_start, col_end }
}
pub fn merge(&self, other: &Self) -> Self {
debug_assert_eq!(self.file, other.file, "cannot merge spans from different files");
Self {
file: self.file.clone(),
line_start: self.line_start.min(other.line_start),
line_end: self.line_end.max(other.line_end),
col_start: if self.line_start <= other.line_start { self.col_start } else { other.col_start },
col_end: if self.line_end >= other.line_end { self.col_end } else { other.col_end },
}
}
}
impl fmt::Display for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.file {
Some(file) => write!(f, "{}:{}:{}", file.display(), self.line_start, self.col_start),
None => write!(f, "line {}:{}", self.line_start, self.col_start),
}
}
}