///|
fn scan_stop_name(stop : ScanStop) -> String {
match stop {
CleanEnd => "clean_end"
TruncatedTail => "truncated_tail"
Corruption => "corruption"
UnsupportedVersion => "unsupported_version"
SequenceViolation => "sequence_violation"
RecordLimit => "record_limit"
}
}
///|
fn json_escape(value : String) -> String {
let output = StringBuilder(size_hint=value.length())
for index = 0; index < value.length(); index = index + 1 {
match value.unsafe_get(index) {
'"' => output.write_string("\\\"")
'\\' => output.write_string("\\\\")
'\n' => output.write_string("\\n")
'\r' => output.write_string("\\r")
'\t' => output.write_string("\\t")
unit => output.write_char(unit.to_int().unsafe_to_char())
}
}
output.to_string()
}
///|
/// Stable machine-readable scan summary.
pub fn ScanResult::to_json(self : ScanResult) -> String {
"{\"records\":\{self.records.length()},\"valid_bytes\":\{self.valid_bytes},\"total_bytes\":\{self.total_bytes},\"stop\":\"\{scan_stop_name(self.stop)}\",\"fault_offset\":\{self.fault_offset},\"message\":\"\{json_escape(self.message)}\"}"
}
///|
fn uint_array_json(values : Array[UInt]) -> String {
let output = StringBuilder()
output.write_char('[')
for index, value in values {
if index > 0 {
output.write_char(',')
}
output.write_string(value.to_string())
}
output.write_char(']')
output.to_string()
}
///|
fn issues_json(issues : Array[RecoveryIssue]) -> String {
let output = StringBuilder()
output.write_char('[')
for index, issue in issues {
if index > 0 {
output.write_char(',')
}
output.write_string(
"{\"code\":\"\{json_escape(issue.code)}\",\"sequence\":\{issue.sequence},\"transaction\":\{issue.transaction},\"message\":\"\{json_escape(issue.message)}\"}",
)
}
output.write_char(']')
output.to_string()
}
///|
/// Stable machine-readable recovery summary and diagnostics.
pub fn RecoveryPlan::to_json(self : RecoveryPlan) -> String {
"{\"recoverable\":\{self.recoverable},\"checkpoint_sequence\":\{self.checkpoint_sequence},\"actions\":\{self.actions.length()},\"committed_transactions\":\{self.committed_transactions},\"aborted_transactions\":\{self.aborted_transactions},\"incomplete_transactions\":\{uint_array_json(self.incomplete_transactions)},\"issues\":\{issues_json(self.issues)}}"
}
///|
/// Stable machine-readable crash-cut verification evidence.
pub fn CrashSweepReport::to_json(self : CrashSweepReport) -> String {
"{\"cuts_checked\":\{self.cuts_checked},\"exact_prefixes\":\{self.exact_prefixes},\"unsafe_replays\":\{self.unsafe_replays},\"passed\":\{self.passed}}"
}
///|
/// Stable machine-readable corruption verification evidence.
pub fn CorruptionSweepReport::to_json(self : CorruptionSweepReport) -> String {
"{\"bits_checked\":\{self.bits_checked},\"corruptions_detected\":\{self.corruptions_detected},\"undetected\":\{self.undetected},\"passed\":\{self.passed}}"
}