use crate::diagnostics::Label;
use super::FileId;
use std::ops::Range;
#[derive(Debug, PartialEq, Eq, Default, Copy, Clone, Hash)]
pub struct Location {
file_id: FileId,
span: Span,
}
impl Location {
pub fn new(file_id: FileId, span: impl Into<Span>) -> Self {
Self {
file_id,
span: span.into(),
}
}
pub fn span(&self) -> Span {
self.span
}
pub fn file_id(&self) -> FileId {
self.file_id
}
}
impl Located for Location {
fn location(&self) -> Location {
*self
}
}
#[derive(Debug, PartialEq, Eq, Default, Copy, Clone, Hash)]
pub struct Span(usize, usize);
impl Span {
pub fn new(start: usize, end: usize) -> Self {
Self(start, end)
}
pub fn start(&self) -> usize {
self.0
}
pub fn end(&self) -> usize {
self.1
}
pub fn until(&self, other: Self) -> Self {
Self::new(self.0, other.1)
}
}
impl From<Span> for Range<usize> {
fn from(span: Span) -> Self {
span.0..span.1
}
}
impl From<Range<usize>> for Span {
fn from(value: Range<usize>) -> Self {
Span::new(value.start, value.end)
}
}
pub trait Located {
fn location(&self) -> Location;
fn span(&self) -> Span {
self.location().span
}
fn file_id(&self) -> FileId {
self.location().file_id
}
fn primary(&self, message: impl Into<String>) -> Label {
Label::new(
codespan_reporting::diagnostic::Label::primary(self.file_id(), self.span())
.with_message(message),
)
}
fn secondary(&self, message: impl Into<String>) -> Label {
Label::new(
codespan_reporting::diagnostic::Label::secondary(self.file_id(), self.span())
.with_message(message),
)
}
}