///|
fn one_based(value : Int) -> Int {
value + 1
}
///|
/// Renders one diagnostic as a stable, grep-friendly line plus notes.
pub fn render_compact(sources : SourceMap, diagnostic : Diagnostic) -> String {
let header = match diagnostic.primary_label() {
None => "\{diagnostic.severity().name()}: \{diagnostic.message()}"
Some(label) =>
match sources.get(label.source()) {
None => "\{diagnostic.severity().name()}: \{diagnostic.message()}"
Some(source) => {
let location = source.location(label.span().start())
"\{source.name()}:\{one_based(location.line())}:\{one_based(location.column())}: \{diagnostic.severity().name()}: \{diagnostic.message()}"
}
}
}
let with_code = match diagnostic.code() {
None => header
Some(code) => "\{header} [\{code}]"
}
let buffer = StringBuilder::new()
buffer.write_string(with_code)
for note in diagnostic.notes() {
buffer.write_string("\n note: ")
buffer.write_string(note)
}
match diagnostic.help() {
Some(help) => {
buffer.write_string("\n help: ")
buffer.write_string(help)
}
None => ()
}
buffer.to_string()
}
///|
/// Renders diagnostics separated by newlines without a trailing newline.
pub fn render_compact_all(
sources : SourceMap,
diagnostics : Array[Diagnostic],
) -> String {
let buffer = StringBuilder::new()
for index, diagnostic in diagnostics {
if index > 0 {
buffer.write_char('\n')
}
buffer.write_string(render_compact(sources, diagnostic))
}
buffer.to_string()
}