konjure_lang/
diagnostics.rs1use crate::Diagnostic;
3use ariadne::{Config, IndexType, Label, Report, ReportKind, Source};
4
5pub fn render_diagnostic(diagnostic: &Diagnostic, source: &str) -> std::io::Result<String> {
11 let span = &diagnostic.span;
12 if span.start > span.end
13 || span.end > source.len()
14 || !source.is_char_boundary(span.start)
15 || !source.is_char_boundary(span.end)
16 {
17 return Err(std::io::Error::new(
18 std::io::ErrorKind::InvalidInput,
19 "diagnostic span does not match source",
20 ));
21 }
22 let mut output = Vec::new();
23 Report::build(
24 ReportKind::Error,
25 (span.module.as_str(), span.start..span.end),
26 )
27 .with_config(
28 Config::default()
29 .with_color(false)
30 .with_index_type(IndexType::Byte),
31 )
32 .with_code(&diagnostic.code)
33 .with_message(&diagnostic.message)
34 .with_label(
35 Label::new((span.module.as_str(), span.start..span.end)).with_message(&diagnostic.message),
36 )
37 .finish()
38 .write((span.module.as_str(), Source::from(source)), &mut output)?;
39 String::from_utf8(output)
40 .map_err(|error| std::io::Error::new(std::io::ErrorKind::InvalidData, error))
41}