///|
/// Single-quote recovery is lexical, never a global replacement.
fn Parser::single_string(self : Parser) -> String raise RepairError {
let start = self.pos
self.pos += 1
let out = StringBuilder()
out.write_string("\"")
while self.peek() != -1 {
let c = self.peek()
self.pos += 1
if c == 39 {
out.write_string("\"")
let candidate = out.to_string()
let decoded = try {
match @json.parse(candidate) {
String(s) => s
_ => raise Rejected("INVALID_STRING", start)
}
} catch {
_ => raise Rejected("INVALID_STRING", start)
}
self.edit(start, self.pos, candidate, "SINGLE_QUOTE")
return decoded
} else if c == 92 {
if self.peek() == -1 {
raise Rejected("UNCLOSED_STRING", start)
}
if self.peek() > 127 {
raise Rejected("INVALID_STRING", start)
}
if self.peek() == 39 {
out.write_string("'")
} else {
out.write_string("\\")
out.write_string(self.source[self.pos:self.pos + 1].to_owned())
}
self.pos += 1
} else if c == 34 {
out.write_string("\\\"")
} else {
if c >= 0xD800 &&
c <= 0xDBFF &&
self.peek() >= 0xDC00 &&
self.peek() <= 0xDFFF {
out.write_string(self.source[self.pos - 1:self.pos + 1].to_owned())
self.pos += 1
continue
}
out.write_string(self.source[self.pos - 1:self.pos].to_owned())
}
}
raise Rejected("UNCLOSED_STRING", start)
}