use std::fmt::Display;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Loc {
pub span: miette::SourceSpan,
pub src: Arc<str>,
}
impl Loc {
pub fn new(span: impl Into<miette::SourceSpan>, src: Arc<str>) -> Self {
Self {
span: span.into(),
src,
}
}
pub fn span(&self, span: impl Into<miette::SourceSpan>) -> Self {
Self {
span: span.into(),
src: Arc::clone(&self.src),
}
}
pub fn start(&self) -> usize {
self.span.offset()
}
pub fn end(&self) -> usize {
self.span.offset() + self.span.len()
}
pub fn snippet(&self) -> Option<&str> {
self.src.get(self.start()..self.end())
}
}
impl Display for Loc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.snippet() {
Some(s) => write!(f, "`{}`", s),
None => write!(f, "``"),
}
}
}
impl From<Loc> for miette::SourceSpan {
fn from(loc: Loc) -> Self {
loc.span
}
}
impl From<&Loc> for miette::SourceSpan {
fn from(loc: &Loc) -> Self {
loc.span
}
}
impl miette::SourceCode for Loc {
fn read_span<'a>(
&'a self,
span: &miette::SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn miette::SpanContents<'a> + 'a>, miette::MietteError> {
self.src
.read_span(span, context_lines_before, context_lines_after)
}
}
impl miette::SourceCode for &Loc {
fn read_span<'a>(
&'a self,
span: &miette::SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn miette::SpanContents<'a> + 'a>, miette::MietteError> {
self.src
.read_span(span, context_lines_before, context_lines_after)
}
}