///|
fn json_escape(value : String) -> String {
let mut output = ""
for character in value {
let code = character.to_int()
if code == 34 {
output = output + "\\\""
} else if code == 92 {
output = output + "\\\\"
} else if code == 8 {
output = output + "\\b"
} else if code == 9 {
output = output + "\\t"
} else if code == 10 {
output = output + "\\n"
} else if code == 12 {
output = output + "\\f"
} else if code == 13 {
output = output + "\\r"
} else if code < 32 {
let digits = "0123456789ABCDEF"
output = output +
"\\u00" +
digits[(code >> 4) & 15].to_char().unwrap().to_string() +
digits[code & 15].to_char().unwrap().to_string()
} else {
output = output + character.to_string()
}
}
output
}
///|
fn json_string(value : String) -> String {
"\"" + json_escape(value) + "\""
}
///|
fn severity_text(severity : ValidationSeverity) -> String {
match severity {
Error => "error"
Warning => "warning"
}
}
///|
fn change_kind_text(kind : ChangeKind) -> String {
match kind {
Added => "added"
Removed => "removed"
Modified => "modified"
}
}
///|
fn optional_int_json(value : Int?) -> String {
match value {
Some(number) => number.to_string()
None => "null"
}
}
///|
fn optional_string_json(value : String?) -> String {
match value {
Some(text) => json_string(text)
None => "null"
}
}
///|
pub fn render_statistics_text(statistics : DbcStatistics) -> String {
let mut output = "DBC statistics\n"
output = output + "nodes: \{statistics.node_count()}\n"
output = output + "messages: \{statistics.message_count()}\n"
output = output + "signals: \{statistics.signal_count()}\n"
output = output + "classic_messages: \{statistics.classic_message_count()}\n"
output = output + "fd_messages: \{statistics.fd_message_count()}\n"
output = output + "intel_signals: \{statistics.intel_signal_count()}\n"
output = output + "motorola_signals: \{statistics.motorola_signal_count()}\n"
output = output + "signed_signals: \{statistics.signed_signal_count()}\n"
output = output + "described_values: \{statistics.described_value_count()}\n"
output = output + "payload_bytes: \{statistics.payload_bytes()}\n"
if !statistics.node_traffic().is_empty() {
output = output + "node_traffic:\n"
for traffic in statistics.node_traffic() {
output = output +
" \{traffic.node()}: tx=\{traffic.transmitted_messages()}, rx_messages=\{traffic.received_messages()}, rx_signals=\{traffic.received_signals()}\n"
}
}
output
}
///|
pub fn render_statistics_json(statistics : DbcStatistics) -> String {
let mut output = "{"
output = output + "\"node_count\":\{statistics.node_count()},"
output = output + "\"message_count\":\{statistics.message_count()},"
output = output + "\"signal_count\":\{statistics.signal_count()},"
output = output +
"\"classic_message_count\":\{statistics.classic_message_count()},"
output = output + "\"fd_message_count\":\{statistics.fd_message_count()},"
output = output + "\"intel_signal_count\":\{statistics.intel_signal_count()},"
output = output +
"\"motorola_signal_count\":\{statistics.motorola_signal_count()},"
output = output +
"\"signed_signal_count\":\{statistics.signed_signal_count()},"
output = output +
"\"described_value_count\":\{statistics.described_value_count()},"
output = output + "\"payload_bytes\":\{statistics.payload_bytes()},"
output = output + "\"node_traffic\":["
for index, traffic in statistics.node_traffic() {
if index > 0 {
output = output + ","
}
output = output +
"{\"node\":" +
json_string(traffic.node()) +
",\"transmitted_messages\":\{traffic.transmitted_messages()}" +
",\"received_messages\":\{traffic.received_messages()}" +
",\"received_signals\":\{traffic.received_signals()}}"
}
output + "]}"
}
///|
pub fn render_validation_text(result : DbcValidationResult) -> String {
let mut output = "DBC validation: errors=\{result.error_count()}, warnings=\{result.warning_count()}\n"
for issue in result.issues() {
output = output + "[\{severity_text(issue.severity())}] \{issue.code()}"
match issue.message_id() {
Some(id) => output = output + " message=\{id}"
None => ()
}
match issue.signal_name() {
Some(name) => output = output + " signal=\{name}"
None => ()
}
output = output + " line=\{issue.source_line()}: \{issue.message()}\n"
}
output
}
///|
pub fn render_validation_json(result : DbcValidationResult) -> String {
let mut output = "{\"valid\":\{result.is_valid()},\"error_count\":\{result.error_count()},\"warning_count\":\{result.warning_count()},\"issues\":["
for index, issue in result.issues() {
if index > 0 {
output = output + ","
}
output = output +
"{\"severity\":" +
json_string(severity_text(issue.severity())) +
",\"code\":" +
json_string(issue.code()) +
",\"message\":" +
json_string(issue.message()) +
",\"message_id\":" +
optional_int_json(issue.message_id()) +
",\"signal_name\":" +
optional_string_json(issue.signal_name()) +
",\"source_line\":\{issue.source_line()}}"
}
output + "]}"
}
///|
pub fn render_comparison_text(comparison : DbcComparison) -> String {
let mut output = "DBC comparison: breaking_changes=\{comparison.breaking_change_count()}\n"
for change in comparison.message_changes() {
output = output +
"[message \{change_kind_text(change.kind())}] id=\{change.message_id()} name=\{change.message_name()} breaking=\{change.is_breaking()}: \{change.detail()}\n"
}
for change in comparison.signal_changes() {
output = output +
"[signal \{change_kind_text(change.kind())}] message=\{change.message_id()} signal=\{change.signal_name()} breaking=\{change.is_breaking()}: \{change.detail()}\n"
}
output
}
///|
pub fn render_comparison_json(comparison : DbcComparison) -> String {
let mut output = "{\"compatible\":\{comparison.is_compatible()},\"breaking_change_count\":\{comparison.breaking_change_count()},\"message_changes\":["
for index, change in comparison.message_changes() {
if index > 0 {
output = output + ","
}
output = output +
"{\"kind\":" +
json_string(change_kind_text(change.kind())) +
",\"message_id\":\{change.message_id()}" +
",\"message_name\":" +
json_string(change.message_name()) +
",\"detail\":" +
json_string(change.detail()) +
",\"breaking\":\{change.is_breaking()}}"
}
output = output + "],\"signal_changes\":["
for index, change in comparison.signal_changes() {
if index > 0 {
output = output + ","
}
output = output +
"{\"kind\":" +
json_string(change_kind_text(change.kind())) +
",\"message_id\":\{change.message_id()}" +
",\"signal_name\":" +
json_string(change.signal_name()) +
",\"detail\":" +
json_string(change.detail()) +
",\"breaking\":\{change.is_breaking()}}"
}
output + "]}"
}
///|
pub fn render_decoded_text(
message : DbcMessage,
decoded : Array[DecodedSignal],
) -> String {
let mut output = "Decoded message \{message.name()} (\{message.id()})\n"
for value in decoded {
output = output +
"\{value.name()}: raw=\{value.signed_raw()}, physical=\{value.physical()}"
match value.label() {
Some(label) => output = output + ", label=\{label}"
None => ()
}
output = output + "\n"
}
output
}
///|
pub fn render_decoded_json(
message : DbcMessage,
decoded : Array[DecodedSignal],
) -> String {
let mut output = "{\"message_id\":\{message.id()},\"message_name\":" +
json_string(message.name()) +
",\"signals\":["
for index, value in decoded {
if index > 0 {
output = output + ","
}
output = output +
"{\"name\":" +
json_string(value.name()) +
",\"raw_bits\":" +
json_string(value.raw_bits().to_string()) +
",\"signed_raw\":\{value.signed_raw()}" +
",\"physical\":\{value.physical()}" +
",\"label\":" +
optional_string_json(value.label()) +
"}"
}
output + "]}"
}