///|
/// One JSONL line's result. Error offsets and edit ranges are line-local UTF-16.
pub(all) struct LineResult {
line : Int
output : String?
edits : Array[Edit]
error_code : String?
error_offset : Int?
} derive(Eq, @debug.Debug, ToJson)
///|
/// Process each physical line independently; blank interior lines are errors.
/// A final newline does not create a phantom record. Aggregate input is bounded.
pub fn repair_jsonl(
input : String,
options? : Options = Options::conservative(),
max_lines? : Int = 10000,
) -> Array[LineResult] raise RepairError {
if max_lines < 1 {
raise Rejected("INVALID_OPTIONS", 0)
}
if input.length() > options.max_input {
raise Rejected("INPUT_LIMIT", 0)
}
if input.length() == 0 {
return []
}
let lines = input.split("\n").to_array()
let count = if input.has_suffix("\n") {
lines.length() - 1
} else {
lines.length()
}
if count > max_lines {
raise Rejected("LINE_LIMIT", 0)
}
let result : Array[LineResult] = []
for i = 0; i < count; i = i + 1 {
let row = try {
let r = repair(lines[i].to_owned(), options~)
LineResult::{
line: i + 1,
output: Some(r.output),
edits: r.edits,
error_code: None,
error_offset: None,
}
} catch {
Rejected(code, offset) =>
{
line: i + 1,
output: None,
edits: [],
error_code: Some(code),
error_offset: Some(offset),
}
}
result.push(row)
}
result
}