2024-01-12 09:36:30 +01:00
|
|
|
use std::process;
|
|
|
|
|
|
|
|
use ron::error::Position;
|
|
|
|
|
2024-01-19 09:51:48 +01:00
|
|
|
/// Report an `Error` from the `serde_json` crate
|
2024-01-12 09:36:30 +01:00
|
|
|
pub fn report_serde_json_err(src: &str, err: serde_json::Error) -> ! {
|
|
|
|
report_serde_err(src, err.line(), err.column(), err.to_string())
|
|
|
|
}
|
|
|
|
|
2024-01-19 09:51:48 +01:00
|
|
|
/// Report a `SpannedError` from the `ron` crate
|
2024-01-12 09:36:30 +01:00
|
|
|
pub fn report_serde_ron_err(src: &str, err: ron::error::SpannedError) -> ! {
|
|
|
|
let Position { line, col } = err.position;
|
|
|
|
report_serde_err(src, line, col, err.to_string())
|
|
|
|
}
|
|
|
|
|
2024-01-19 09:51:48 +01:00
|
|
|
/// Basic function for reporting serde type of errors
|
|
|
|
fn report_serde_err(src: &str, line: usize, col: usize, msg: String) -> ! {
|
2024-01-12 09:36:30 +01:00
|
|
|
use ariadne::{Label, Report, Source};
|
|
|
|
let offset = try_reconstruct_loc(src, line, col);
|
|
|
|
|
|
|
|
Report::build(ariadne::ReportKind::Error, "test", offset)
|
|
|
|
.with_label(Label::new(("test", offset..offset)).with_message("Something went wrong here!"))
|
|
|
|
.with_message(msg)
|
|
|
|
.with_note("We'd like to give better errors, but serde errors are horrible to work with...")
|
|
|
|
.finish()
|
|
|
|
.print(("test", Source::from(src)))
|
|
|
|
.unwrap();
|
|
|
|
process::exit(1);
|
|
|
|
}
|
2024-01-19 09:51:48 +01:00
|
|
|
|
|
|
|
/// Reconstruct a byte offset from the line + column numbers typical from serde crates
|
2024-01-12 09:36:30 +01:00
|
|
|
fn try_reconstruct_loc(src: &str, line_nr: usize, col_nr: usize) -> usize {
|
|
|
|
let (line_nr, col_nr) = (line_nr - 1, col_nr - 1);
|
|
|
|
|
|
|
|
src.lines()
|
|
|
|
.enumerate()
|
|
|
|
.fold(0, |acc, (i, line)| match i.cmp(&line_nr) {
|
|
|
|
std::cmp::Ordering::Less => acc + line.len() + 1,
|
|
|
|
std::cmp::Ordering::Equal => acc + col_nr,
|
|
|
|
std::cmp::Ordering::Greater => acc,
|
|
|
|
})
|
|
|
|
}
|