///|
fn structured_escape(value : String) -> String {
let builder = StringBuilder()
for character in value {
match character {
'"' => builder.write_string("\\\"")
'\\' => builder.write_string("\\\\")
'\n' => builder.write_string("\\n")
'\r' => builder.write_string("\\r")
'\t' => builder.write_string("\\t")
_ => builder.write_char(character)
}
}
builder.to_string()
}
///|
/// Render a stable machine-readable report around diagnostics from one source.
pub fn render_report_json(
diagnostics : Array[Diagnostic],
source : @source.SourceFile,
file_name : String,
) -> String {
let errors = diagnostics.filter(fn(item) { item.severity is Error }).length()
let warnings = diagnostics
.filter(fn(item) { item.severity is Warning })
.length()
let builder = StringBuilder()
builder.write_string("{\"file\":\"")
builder.write_string(
structured_escape(
if file_name.is_empty() {
source.name()
} else {
file_name
},
),
)
builder.write_string("\",\"count\":")
builder.write_object(diagnostics.length())
builder.write_string(",\"errors\":")
builder.write_object(errors)
builder.write_string(",\"warnings\":")
builder.write_object(warnings)
builder.write_string(",\"diagnostics\":[")
for index, diagnostic in diagnostics {
if index > 0 {
builder.write_char(',')
}
builder.write_string("{\"code\":\"")
builder.write_string(structured_escape(diagnostic.code))
builder.write_string("\",\"severity\":\"")
builder.write_string(diagnostic.severity.label())
builder.write_string("\",\"message\":\"")
builder.write_string(structured_escape(diagnostic.message))
builder.write_string("\"}")
}
builder.write_string("]}\n")
builder.to_string()
}