#![doc = include_str!("../README.md")]
use ariadne::{Color, Report, Source};
use std::{fmt::Debug, io::Write, ops::Range};
pub const EXPR: Color = Color::RGB(52, 235, 152);
pub trait ErrorKind: Debug + Send {
fn build_report<'a>(
&self,
src_id: &'a str,
spans: &[Range<usize>],
) -> Report<(&'a str, Range<usize>)>;
}
#[derive(Debug)]
pub struct Error {
pub spans: Vec<Range<usize>>,
pub kind: Box<dyn ErrorKind>,
}
impl Error {
pub fn new(spans: Vec<Range<usize>>, kind: impl ErrorKind + 'static) -> Self {
Self { spans, kind: Box::new(kind) }
}
pub fn build_report<'a>(&self, src_id: &'a str) -> Report<(&'a str, Range<usize>)> {
self.kind.build_report(src_id, &self.spans)
}
pub fn report_to_stderr(&self, src_id: &str, input: &str) -> std::io::Result<()> {
self.report_to(std::io::stderr(), src_id, input)
}
pub fn report_to<W: Write>(
&self,
writer: W,
src_id: &str,
input: &str,
) -> std::io::Result<()> {
let report = self.build_report(src_id);
report.write((src_id, Source::from(input)), writer)
}
}