Declarative JSON data manipulation for OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

json: drop [encode] result form; rename [encode_exn] to [encode]

Per the ocaml-encodings convention, encoding never has a meaningful
runtime failure mode: the encoder walks the GADT and invokes
user-supplied [enc] callbacks. The only failure cases are (a) a codec
built around [Codec.ignore] (programmer error), or (b) a user-
supplied [enc] that raises (user's own bug). Neither is something a
caller should recover from, so the [result] variant was dead API
surface and every caller I've seen either [get_ok]-ed it or fell
back to [Json.Null] on error.

Drop [Codec.encode] / [Json.encode] result-returning, rename the
exception-raising [encode_exn] to just [encode]. [decode] keeps both
forms since malformed JSON is a legitimate runtime condition.

Downstream sweep: 28 files across claude / oci / atp / qemu / scitt /
yaml. Most were pattern A ([Error _ -> Json.Null ((), Meta.none)]) or
pattern B (print the error); both collapse to a direct call. Tests
using pattern F ([match Json.encode ... with Ok j -> ... | Error e
-> Alcotest.fail]) collapse to [let j = Json.encode ... in]. A few
helpers in claude/client.ml and the atp shims kept their names as
thin aliases to preserve grep targets.

+20 -28
+16 -17
lib/codec.ml
··· 1382 1382 end 1383 1383 1384 1384 (* Decode / encode between generic JSON and typed values using a codec. 1385 - [decode_exn] / [encode_exn] raise [Error]; thin wrappers return results. *) 1385 + [decode_exn] / [encode] raise [Error]; the result-form wrapper is only on 1386 + [decode] since encoding only fails through broken codecs. *) 1386 1387 1387 1388 let error_sort ~exp j = Error.fail_sort (Ast.meta j) ~exp ~fnd:(Ast.sort j) 1388 1389 ··· 1591 1592 1592 1593 (* Encode *) 1593 1594 1594 - let rec encode_exn : type a. a t -> a -> Ast.t = 1595 + let rec encode : type a. a t -> a -> Ast.t = 1595 1596 fun t v -> 1596 1597 match t with 1597 1598 | Null map -> Ast.null ~meta:(map.enc_meta v) (map.enc v) ··· 1600 1601 | String map -> Ast.string ~meta:(map.enc_meta v) (map.enc v) 1601 1602 | Array map -> 1602 1603 let enc map acc i elt = 1603 - try encode_exn map.elt elt :: acc 1604 + try encode map.elt elt :: acc 1604 1605 with Error e -> fail_push_array Meta.none map (i, Meta.none) e 1605 1606 in 1606 1607 Ast.list ~meta:(map.enc_meta v) (List.rev (map.enc (enc map) [] v)) 1607 1608 | Object map -> 1608 1609 let mems = encode_object map ~do_unknown:true v [] in 1609 1610 Ast.Object (List.rev mems, map.enc_meta v) 1610 - | Any map -> encode_exn (map.enc v) v 1611 - | Map map -> encode_exn map.dom (map.enc v) 1612 - | Rec t -> encode_exn (Lazy.force t) v 1611 + | Any map -> encode (map.enc v) v 1612 + | Map map -> encode map.dom (map.enc v) 1613 + | Rec t -> encode (Lazy.force t) v 1613 1614 | Ignore -> Error.fail_no_encoder Meta.none ~kind:"ignore" 1614 1615 1615 1616 and encode_object : type o. ··· 1619 1620 try 1620 1621 let v = mmap.enc o in 1621 1622 if mmap.enc_omit v then obj 1622 - else ((mmap.name, Meta.none), encode_exn mmap.type' v) :: obj 1623 + else ((mmap.name, Meta.none), encode mmap.type' v) :: obj 1623 1624 with Error e -> fail_push_object Meta.none map (mmap.name, Meta.none) e 1624 1625 in 1625 1626 let obj = List.fold_left (encode_mem map) obj map.mem_encs in ··· 1633 1634 let n = (cases.tag.name, Meta.none) in 1634 1635 try 1635 1636 if cases.tag.enc_omit case.tag then obj 1636 - else (n, encode_exn cases.tag.type' case.tag) :: obj 1637 + else (n, encode cases.tag.type' case.tag) :: obj 1637 1638 with Error e -> fail_push_object Meta.none map n e 1638 1639 in 1639 1640 match u with ··· 1652 1653 let encode_mem map meta name v obj = 1653 1654 let n = (name, meta) in 1654 1655 let v = 1655 - try encode_exn umap.mems_type v 1656 + try encode umap.mems_type v 1656 1657 with Error e -> fail_push_object Meta.none map n e 1657 1658 in 1658 1659 (n, v) :: obj 1659 1660 in 1660 1661 umap.enc (encode_mem map) mems obj 1661 1662 1662 - let encode t v = try Ok (encode_exn t v) with Error e -> Result.Error e 1663 - 1664 1663 (* Recode: decode then encode (on values). The [recode] combinator above 1665 1664 takes labelled [~dec]/[~enc] args; these operate on values. *) 1666 1665 1667 - let value_recode_exn t v = encode_exn t (decode_exn t v) 1666 + let value_recode_exn t v = encode t (decode_exn t v) 1668 1667 1669 1668 (* Queries and updates *) 1670 1669 ··· 1725 1724 match absent with 1726 1725 | None -> Error.fail_index_out_of_range meta ~n ~len 1727 1726 | Some absent -> 1728 - let elt = encode_exn t absent in 1727 + let elt = encode t absent in 1729 1728 let stub = 1730 1729 match stub with None -> Ast.zero elt | Some j -> j 1731 1730 in ··· 1762 1761 let dec_add i v acc = 1763 1762 match f i (decode_exn a v) with 1764 1763 | None -> acc 1765 - | Some v' -> encode_exn b v' :: acc 1764 + | Some v' -> encode b v' :: acc 1766 1765 in 1767 1766 let dec_finish meta _len acc = Ast.list ~meta (List.rev acc) in 1768 1767 let enc f acc = function ··· 1809 1808 Error.fail_missing_members meta ~kinded_sort:"" ~exp:[ name ] 1810 1809 ~fnd 1811 1810 | Some absent -> 1812 - let m = ((name, Meta.none), encode_exn t absent) in 1811 + let m = ((name, Meta.none), encode t absent) in 1813 1812 List.rev (m :: acc)) 1814 1813 in 1815 1814 (Ast.Object (mems, meta) : Ast.t) ··· 1870 1869 let dec_add meta n v (_, mems) = 1871 1870 match f meta n (decode_exn a v) with 1872 1871 | None -> (true, mems) 1873 - | Some (n', v') -> (true, (n', encode_exn b v') :: mems) 1872 + | Some (n', v') -> (true, (n', encode b v') :: mems) 1874 1873 in 1875 1874 let dec_finish _meta acc = acc in 1876 1875 update_value_object ~name:"" ~dec_add ~dec_finish ··· 1952 1951 1953 1952 let set_path ?stub ?(allow_absent = false) t p v = 1954 1953 match Path.rev_steps p with 1955 - | [] -> recode ~dec:ignore (fun () -> encode_exn t v) ~enc:Value.t 1954 + | [] -> recode ~dec:ignore (fun () -> encode t v) ~enc:Value.t 1956 1955 | _ :: _ -> 1957 1956 let absent = if allow_absent then Some v else None in 1958 1957 update_path ?stub ?absent p (const t v)
+1 -4
lib/codec.mli
··· 1233 1233 val decode_exn : 'a t -> value -> 'a 1234 1234 (** [decode_exn] is like {!val-decode} but raises the exception {!Error}. *) 1235 1235 1236 - val encode : 'a t -> 'a -> (value, Error.t) result 1236 + val encode : 'a t -> 'a -> value 1237 1237 (** [encode t v] encodes [v] as a generic JSON value according to [t]. *) 1238 - 1239 - val encode_exn : 'a t -> 'a -> value 1240 - (** [encode_exn] is like {!val-encode} but raises the exception {!Error}. *) 1241 1238 1242 1239 (** {1:stream Byte-stream I/O} 1243 1240
+2 -3
lib/json.ml
··· 38 38 let decode = Codec.decode 39 39 let decode_exn = Codec.decode_exn 40 40 let encode = Codec.encode 41 - let encode_exn = Codec.encode_exn 42 41 43 42 let pp_value ?(number_format = Value.default_number_format) t () ppf v = 44 43 match encode t v with 45 - | Ok j -> Value.pp' number_format ppf j 46 - | Error e -> Value.pp_string ppf (Error.to_string e) 44 + | j -> Value.pp' number_format ppf j 45 + | exception Error e -> Value.pp_string ppf (Loc.Error.to_string e) 47 46 48 47 let of_reader = Codec.Stream.of_reader 49 48 let of_reader_exn = Codec.Stream.of_reader_exn
+1 -4
lib/json.mli
··· 137 137 val decode_exn : 'a codec -> t -> 'a 138 138 (** [decode_exn] is like {!val-decode} but raises {!Json.exception-Error}. *) 139 139 140 - val encode : 'a codec -> 'a -> (t, Error.t) result 140 + val encode : 'a codec -> 'a -> t 141 141 (** [encode c v] encodes OCaml value [v] as a generic JSON value according to 142 142 codec [c]. *) 143 - 144 - val encode_exn : 'a codec -> 'a -> t 145 - (** [encode_exn] is like {!val-encode} but raises {!Json.exception-Error}. *) 146 143 147 144 (** {1:decode Decode} *) 148 145