use std::fmt;
use std::rc::Rc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Loc {
pub pos: usize,
pub row: usize,
pub col: usize,
}
impl Loc {
#[inline]
pub fn new(pos: usize, row: usize, col: usize) -> Self {
Loc {
pos,
row,
col,
}
}
#[inline]
pub fn zero() -> Self {
Default::default()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SpanT<F, L> {
pub file_name: F,
pub start: L,
pub end: L,
}
pub type Span<'f, L> = SpanT<&'f str, L>;
pub type SpanRc<L> = SpanT<Rc<String>, L>;
impl<F, L> SpanT<F, L> {
#[inline]
pub fn new(file_name: F, start: L, end: L) -> Self {
SpanT {
file_name,
start,
end,
}
}
}
impl<F, L: Clone> SpanT<F, L> {
#[inline]
pub fn empty(file_name: F, loc: L) -> Self {
SpanT::new(file_name, loc.clone(), loc)
}
}
impl<F, L: Default> SpanT<F, L> {
#[inline]
pub fn zero(file_name: F) -> Self {
SpanT::new(file_name, Default::default(), Default::default())
}
}
impl<'f, L: Clone> Span<'f, L> {
pub fn with_rc(&self) -> SpanRc<L> {
SpanT::new(Rc::new(self.file_name.to_owned()), self.start.clone(), self.end.clone())
}
pub fn with_owned(&self) -> SpanT<String, L> {
SpanT::new(self.file_name.to_owned(), self.start.clone(), self.end.clone())
}
}
impl fmt::Display for Loc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{},{}", self.row + 1, self.col + 1)
}
}
impl<F: fmt::Display> fmt::Display for SpanT<F, Loc> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.start.row == self.end.row {
if self.start.col == self.end.col {
write!(
f,
"{}:{},{}",
self.file_name,
self.start.row + 1,
self.start.col + 1,
)
} else {
write!(
f,
"{}:{},{}-{}",
self.file_name,
self.start.row + 1,
self.start.col + 1,
self.end.col + 1,
)
}
} else {
write!(
f,
"{}:{},{}-{},{}",
self.file_name,
self.start.row + 1,
self.start.col + 1,
self.end.row + 1,
self.end.col + 1,
)
}
}
}