OCaml flat JSON decoder with entry-index errors
OCaml
exception Json_error of string
(* Decode a flat JSON object of string fields, reporting the failing entry. *)
let decode_flat src =
let fail msg = raise (Json_error msg) in
let s = String.trim src and n = String.length (String.trim src) in
if n < 2 || s.[0] <> '{' || s.[n - 1] <> '}' then fail "expected an object {...}";
if n = 2 then []
else
String.sub s 1 (n - 2)
|> String.split_on_char ','
|> List.mapi (fun i pair ->
match String.index_opt pair ':' with
| None -> fail (Printf.sprintf "entry %d: missing ':' in %S" i (String.trim pair))
| Some k ->
let key = String.trim (String.sub pair 0 k) in
let raw = String.trim (String.sub pair (k + 1) (String.length pair - k - 1)) in
let unquote what text =
let m = String.length text in
if m >= 2 && text.[0] = '"' && text.[m - 1] = '"' then Scanf.unescaped (String.sub text 1 (m - 2))
else fail (Printf.sprintf "entry %d: %s must be a quoted string, got %S" i what text)
in
(unquote "key" key, unquote "value" raw))