use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub struct Position {
pub line: usize,
pub column: usize,
}
impl Position {
pub fn new(line: usize, column: usize) -> Position {
Position { line, column }
}
pub fn line(&self) -> usize {
self.line
}
pub fn column(&self) -> usize {
self.column
}
}
impl fmt::Display for Position {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}:{}", self.line, self.column)
}
}
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub struct Span {
pub begin: Position,
pub end: Position,
}
impl Span {
pub fn new(begin_line: usize, begin_column: usize, end_line: usize, end_column: usize) -> Self {
Self {
begin: Position::new(begin_line, begin_column),
end: Position::new(end_line, end_column),
}
}
pub fn from_begin_end<Pos>(begin: Pos, end: Pos) -> Self
where
Pos: Into<Position>,
{
Self {
begin: begin.into(),
end: end.into(),
}
}
pub fn merge(self, other: Span) -> Span {
Span {
begin: self.begin,
end: other.end,
}
}
}
impl Default for Span {
fn default() -> Self {
Self {
begin: Position::new(usize::MIN, usize::MIN),
end: Position::new(usize::MAX, usize::MAX),
}
}
}
impl Display for Span {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{} - {}", self.begin, self.end)
}
}
pub trait Spanned {
fn set_span_begin(&mut self, begin: Position) {
self.span_mut().begin = begin;
}
fn set_span_end(&mut self, end: Position) {
self.span_mut().end = end;
}
fn span(&self) -> &Span;
fn span_mut(&mut self) -> &mut Span;
}