Declarative JSON data manipulation for OCaml
0
fork

Configure Feed

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

json: split Sort into sort.ml

Move Sort out of Core (where it was private) into its own sort.ml at
the top level. Sort is a public type referenced from Error.Sort
signatures, Value.sort, and Loc.Path frames; hiding it in a private
module was inconsistent with its public role.

json.mli previously re-declared Sort.t via a [type t = Core.Sort.t = ...]
pin to expose the constructors through the public module. Replace with
a direct [module Sort = Sort] re-export, which is simpler and matches
the pattern the skill now recommends across all encoding libraries.

+76 -103
+1 -1
lib/codec.ml
··· 7 7 module Fmt = Core.Fmt 8 8 module Meta = Loc.Meta 9 9 module Path = Loc.Path 10 - module Sort = Core.Sort 10 + module Sort = Sort 11 11 module String_map = Map.Make (String) 12 12 13 13 type 'a node = 'a * Meta.t
+1 -1
lib/codec.mli
··· 4 4 5 5 module Meta = Loc.Meta 6 6 module Path = Loc.Path 7 - module Sort = Core.Sort 7 + module Sort = Sort 8 8 9 9 type 'a node = 'a * Meta.t 10 10
-18
lib/core.ml
··· 410 410 end 411 411 412 412 (* JSON Paths *) 413 - (* JSON sorts *) 414 - 415 - module Sort = struct 416 - type t = Null | Bool | Number | String | Array | Object 417 - 418 - let to_string = function 419 - | Null -> "null" 420 - | Bool -> "bool" 421 - | Number -> "number" 422 - | String -> "string" 423 - | Array -> "array" 424 - | Object -> "object" 425 - 426 - let kinded' ~kind:k s = if k = "" then s else String.concat " " [ k; s ] 427 - let kinded ~kind sort = kinded' ~kind (to_string sort) 428 - let or_kind ~kind sort = if kind <> "" then kind else to_string sort 429 - let pp ppf s = Fmt.code ppf (to_string s) 430 - end
-28
lib/core.mli
··· 200 200 (** [in_exact_int64_range f] is [true] iff [f] is exactly representable as an 201 201 [int64]. *) 202 202 end 203 - 204 - (** See {!Json.Sort} *) 205 - module Sort : sig 206 - type t = 207 - | Null 208 - | Bool 209 - | Number 210 - | String 211 - | Array 212 - | Object (** The type for JSON value sorts. *) 213 - 214 - val to_string : t -> string 215 - (** [to_string sort] is the lowercase JSON name of [sort]. *) 216 - 217 - val kinded' : kind:string -> string -> string 218 - (** [kinded' ~kind s] is [s] when [kind] is empty, [kind] followed by a space 219 - and [s] otherwise. *) 220 - 221 - val kinded : kind:string -> t -> string 222 - (** [kinded ~kind sort] is {!kinded'} applied to [to_string sort]. *) 223 - 224 - val or_kind : kind:string -> t -> string 225 - (** [or_kind ~kind sort] is [kind] if non-empty, [to_string sort] otherwise. 226 - *) 227 - 228 - val pp : Format.formatter -> t -> unit 229 - (** [pp] formats sorts using {!to_string}. *) 230 - end
+1 -1
lib/error.ml
··· 2 2 kinds and high-level message helpers used by the codec. *) 3 3 4 4 module Fmt = Core.Fmt 5 - module Sort = Core.Sort 5 + module Sort = Sort 6 6 7 7 type kind = Loc.Error.kind = .. 8 8
+1 -1
lib/error.mli
··· 1 1 (** JSON-specific error helpers. Extends {!Loc.Error} with typed error kinds and 2 2 high-level message helpers used by the codec. *) 3 3 4 - module Sort = Core.Sort 4 + module Sort = Sort 5 5 6 6 type kind = Loc.Error.kind = .. 7 7 (** The type for error kinds. This is an alias for the extensible
+5 -13
lib/json.ml
··· 13 13 14 14 module Path = Loc.Path 15 15 module Context = Loc.Context 16 - module Sort = Core.Sort 16 + module Sort = Sort 17 17 18 18 exception Error = Loc.Error 19 19 ··· 2161 2161 err_exp_in_const ~first_byte ~first_line_num ~first_line_byte d ~exp:c 2162 2162 ~fnd:d.u ~const:(ascii_str const) 2163 2163 done; 2164 - let loc = 2165 - loc_to_current d ~first_byte ~first_line_num ~first_line_byte 2166 - in 2164 + let loc = loc_to_current d ~first_byte ~first_line_num ~first_line_byte in 2167 2165 let ws_after = 2168 2166 nextc d; 2169 2167 read_ws d; ··· 2305 2303 nextc d; 2306 2304 token_clear d; 2307 2305 loop d; 2308 - let loc = 2309 - loc_to_current d ~first_byte ~first_line_num ~first_line_byte 2310 - in 2306 + let loc = loc_to_current d ~first_byte ~first_line_num ~first_line_byte in 2311 2307 let ws_after = 2312 2308 nextc d; 2313 2309 read_ws d; ··· 2537 2533 with Error e -> 2538 2534 Error.adjust_context ~first_byte ~first_line_num ~first_line_byte e) 2539 2535 in 2540 - let loc = 2541 - loc_to_current d ~first_byte ~first_line_num ~first_line_byte 2542 - in 2536 + let loc = loc_to_current d ~first_byte ~first_line_num ~first_line_byte in 2543 2537 let ws_after = 2544 2538 nextc d; 2545 2539 read_ws d; ··· 2571 2565 | Error e -> 2572 2566 Error.adjust_context ~first_byte ~first_line_num ~first_line_byte e 2573 2567 in 2574 - let loc = 2575 - loc_to_current d ~first_byte ~first_line_num ~first_line_byte 2576 - in 2568 + let loc = loc_to_current d ~first_byte ~first_line_num ~first_line_byte in 2577 2569 let ws_after = 2578 2570 nextc d; 2579 2571 read_ws d;
+4 -33
lib/json.mli
··· 43 43 module Context = Loc.Context 44 44 (** Navigation contexts (path + source loc + active sort). *) 45 45 46 - (** Sorts of JSON values. *) 47 - module Sort : sig 48 - (** The type for sorts of JSON values. *) 49 - type t = Core.Sort.t = 50 - | Null (** Nulls *) 51 - | Bool (** Booleans *) 52 - | Number (** Numbers *) 53 - | String (** Strings *) 54 - | Array (** Arrays *) 55 - | Object (** Objects *) 56 - 57 - val to_string : t -> string 58 - (** [to_string sort] is a string for sort [sort]. *) 59 - 60 - val pp : Format.formatter -> t -> unit 61 - (** [pp] formats sorts. *) 62 - 63 - (** {1:kinds Kinds} 64 - 65 - For formatting error messages. *) 66 - 67 - val or_kind : kind:string -> t -> string 68 - (** [or_kind ~kind sort] is [to_string sort] if [kind] is [""] and [kind] 69 - otherwise. *) 70 - 71 - val kinded : kind:string -> t -> string 72 - (** [kinded ~kind sort] is [to_string sort] if [kind] is [""] and 73 - [String.concat " " [kind; to_string sort]] otherwise. *) 74 - 75 - val kinded' : kind:string -> string -> string 76 - (** [kinded' ~kind sort] is [sort] if [kind] is [""] and 77 - [String.concat " " [kind; sort]] otherwise. *) 78 - end 46 + module Sort = Sort 47 + (** Sorts of JSON values ({!Sort.Null}, {!Sort.Bool}, {!Sort.Number}, 48 + {!Sort.String}, {!Sort.Array}, {!Sort.Object}). Labels used in structured 49 + error contexts and {!Loc.Path} frames. *) 79 50 80 51 (** Encoding, decoding and query errors. *) 81 52 module Error : sig
+21
lib/sort.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2026 Thomas Gazagnaire <thomas@gazagnaire.org>. 3 + All rights reserved. SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + module Fmt = Core.Fmt 7 + 8 + type t = Null | Bool | Number | String | Array | Object 9 + 10 + let to_string = function 11 + | Null -> "null" 12 + | Bool -> "bool" 13 + | Number -> "number" 14 + | String -> "string" 15 + | Array -> "array" 16 + | Object -> "object" 17 + 18 + let kinded' ~kind:k s = if k = "" then s else String.concat " " [ k; s ] 19 + let kinded ~kind sort = kinded' ~kind (to_string sort) 20 + let or_kind ~kind sort = if kind <> "" then kind else to_string sort 21 + let pp ppf s = Fmt.code ppf (to_string s)
+35
lib/sort.mli
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2026 Thomas Gazagnaire <thomas@gazagnaire.org>. 3 + All rights reserved. SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** JSON value sorts, used as labels in error contexts and {!Loc.Path} frames. 7 + 8 + A {e sort} is the closed enumeration of node categories the JSON grammar 9 + defines (RFC 8259): null, bool, number, string, array, object. A {e kind} is 10 + the specific human-readable label for one instance, built from a sort plus 11 + an identifier, e.g. ["member email"] or ["list of users"]. *) 12 + 13 + type t = 14 + | Null 15 + | Bool 16 + | Number 17 + | String 18 + | Array 19 + | Object (** The type for JSON value sorts. *) 20 + 21 + val to_string : t -> string 22 + (** [to_string sort] is the lowercase JSON name of [sort]. *) 23 + 24 + val kinded' : kind:string -> string -> string 25 + (** [kinded' ~kind s] is [s] when [kind] is empty, [kind] followed by a space 26 + and [s] otherwise. *) 27 + 28 + val kinded : kind:string -> t -> string 29 + (** [kinded ~kind sort] is {!kinded'} applied to [to_string sort]. *) 30 + 31 + val or_kind : kind:string -> t -> string 32 + (** [or_kind ~kind sort] is [kind] if non-empty, [to_string sort] otherwise. *) 33 + 34 + val pp : Format.formatter -> t -> unit 35 + (** [pp] formats sorts using {!to_string}, styled as code. *)
+6 -6
lib/value.ml
··· 93 93 let copy_layout v ~dst = set_meta (Meta.copy_ws (meta v) ~dst:(meta dst)) dst 94 94 95 95 let sort = function 96 - | Null _ -> Core.Sort.Null 97 - | Bool _ -> Core.Sort.Bool 98 - | Number _ -> Core.Sort.Number 99 - | String _ -> Core.Sort.String 100 - | Array _ -> Core.Sort.Array 101 - | Object _ -> Core.Sort.Object 96 + | Null _ -> Sort.Null 97 + | Bool _ -> Sort.Bool 98 + | Number _ -> Sort.Number 99 + | String _ -> Sort.String 100 + | Array _ -> Sort.Array 101 + | Object _ -> Sort.Object 102 102 103 103 (* Equality and comparison *) 104 104
+1 -1
lib/value.mli
··· 48 48 (** [copy_layout src ~dst] copies [src]'s whitespace/layout metadata onto [dst]. 49 49 *) 50 50 51 - val sort : t -> Core.Sort.t 51 + val sort : t -> Sort.t 52 52 (** [sort v] is the JSON sort of [v]. *) 53 53 54 54 (** {1:compare Equality and ordering} *)