///|
/// A human-readable remediation hint for validation errors.
pub(all) struct FixSuggestion {
row : Int
column : String
code : String
suggestion : String
} derive(Eq)
///|
fn suggestion_for_error(err : ValidationError) -> String {
match err.code {
"required" => "fill a non-empty value"
"type" => "convert the value to the expected type or relax the schema"
"missing_column" => "add the required column to the header row"
"extra_column" => "remove the column or validate with an open schema"
_ => "inspect the source data near this location"
}
}
///|
/// Convert validation errors into deterministic repair suggestions.
pub fn suggest_fixes(report : ValidationReport) -> Array[FixSuggestion] {
let suggestions : Array[FixSuggestion] = []
for err in report.errors {
suggestions.push({
row: err.row,
column: err.column,
code: err.code,
suggestion: suggestion_for_error(err),
})
}
suggestions
}
///|
fn write_validation_markdown_row(
out : StringBuilder,
row : String,
column : String,
code : String,
message : String,
) -> Unit {
out.write_string("| ")
out.write_string(markdown_escape_cell(row))
out.write_string(" | ")
out.write_string(markdown_escape_cell(column))
out.write_string(" | ")
out.write_string(markdown_escape_cell(code))
out.write_string(" | ")
out.write_string(markdown_escape_cell(message))
out.write_string(" |\n")
}
///|
/// Render validation errors as a Markdown table.
pub fn ValidationReport::to_markdown(self : ValidationReport) -> String {
let out = StringBuilder::StringBuilder()
write_validation_markdown_row(out, "row", "column", "code", "message")
write_validation_markdown_row(out, "---", "---", "---", "---")
for err in self.errors {
write_validation_markdown_row(
out,
err.row.to_string(),
err.column,
err.code,
err.message,
)
}
out.to_string()
}