///|
fn severity_name(severity : Severity) -> String {
match severity {
Error => "error"
Warning => "warning"
Information => "information"
}
}
///|
fn location_json(location : SourceLocation) -> String {
"{\"file\":\"" +
json_escape(location.file) +
"\",\"line\":" +
location.line.to_string() +
",\"column\":" +
location.column.to_string() +
",\"offset\":" +
location.offset.to_string() +
"}"
}
///|
fn diagnostic_json(diagnostic : Diagnostic) -> String {
"{\"severity\":\"" +
severity_name(diagnostic.severity) +
"\",\"code\":\"" +
json_escape(diagnostic.code) +
"\",\"message\":\"" +
json_escape(diagnostic.message) +
"\",\"hint\":\"" +
json_escape(diagnostic.hint) +
"\",\"start\":" +
location_json(diagnostic.span.start) +
",\"end\":" +
location_json(diagnostic.span.end) +
"}"
}
///|
fn step_json(step : PropertyStep) -> String {
"{\"key\":\"" +
json_escape(step.key) +
"\",\"value\":\"" +
json_escape(step.value) +
"\",\"configPath\":\"" +
json_escape(step.config_path) +
"\",\"pattern\":\"" +
json_escape(step.pattern) +
"\",\"line\":" +
step.line.to_string() +
",\"action\":\"" +
json_escape(step.action) +
"\"}"
}
///|
fn property_json(property : ResolvedProperty) -> String {
let history : Array[String] = []
for step in property.history {
history.push(step_json(step))
}
"{\"key\":\"" +
json_escape(property.key) +
"\",\"value\":\"" +
json_escape(property.value) +
"\",\"configPath\":\"" +
json_escape(property.config_path) +
"\",\"pattern\":\"" +
json_escape(property.pattern) +
"\",\"source\":" +
location_json(property.source) +
",\"history\":[" +
history.join(",") +
"]}"
}
///|
fn trace_json(trace : SectionTrace) -> String {
"{\"configPath\":\"" +
json_escape(trace.config_path) +
"\",\"pattern\":\"" +
json_escape(trace.pattern) +
"\",\"matched\":" +
bool_text(trace.matched) +
",\"relativePath\":\"" +
json_escape(trace.relative_path) +
"\",\"line\":" +
trace.line.to_string() +
",\"reason\":\"" +
json_escape(trace.reason) +
"\"}"
}
///|
pub fn Resolution::to_json(self : Resolution, indent? : Bool = false) -> String {
let properties : Array[String] = []
let sections : Array[String] = []
let diagnostics : Array[String] = []
for property in self.properties {
properties.push(property_json(property))
}
for section in self.sections {
sections.push(trace_json(section))
}
for diagnostic in self.diagnostics {
diagnostics.push(diagnostic_json(diagnostic))
}
let compact = "{\"target\":\"" +
json_escape(self.target) +
"\",\"properties\":[" +
properties.join(",") +
"],\"sections\":[" +
sections.join(",") +
"],\"diagnostics\":[" +
diagnostics.join(",") +
"]}"
if indent {
pretty_json(compact)
} else {
compact
}
}
///|
fn pretty_json(compact : String) -> String {
let output = StringBuilder::new()
let mut depth = 0
let mut quoted = false
let mut escaped = false
for ch in compact {
if quoted {
output.write_char(ch)
if escaped {
escaped = false
} else if ch == '\\' {
escaped = true
} else if ch == '"' {
quoted = false
}
} else {
match ch {
'"' => {
quoted = true
output.write_char(ch)
}
'{' | '[' => {
output.write_char(ch)
output.write_char('\n')
depth += 1
for _ in 0.. {
output.write_char('\n')
depth -= 1
for _ in 0.. {
output.write_char(ch)
output.write_char('\n')
for _ in 0.. output.write_string(": ")
_ => output.write_char(ch)
}
}
}
output.to_string()
}