OCaml Zarr jsont codecs for v2/v3 and common conventions
0
fork

Configure Feed

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

refactor: remove dtype_jsont_fwd mutable ref

Use let rec with a lazy value and Jsont.rec' instead of a mutable
forward reference. The lazy block binds self = Jsont.rec' dtype_jsont_lazy
and uses it directly for recursive decode/encode of nested structured
dtypes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+17 -22
+17 -22
src/zarr_jsont.ml
··· 172 172 | `Raw n -> Printf.sprintf "|V%d" n 173 173 | `Structured _ -> invalid_arg "dtype: encode_typestr called on structured dtype" 174 174 175 - (* Forward reference to allow recursive dtype_jsont. *) 176 - let dtype_jsont_fwd : dtype Jsont.t ref = ref (Jsont.todo ~kind:"dtype" ()) 177 - 178 - let dtype_jsont : dtype Jsont.t = Jsont.rec' (lazy ( 175 + let rec dtype_jsont_lazy : dtype Jsont.t Lazy.t = lazy ( 176 + let self = Jsont.rec' dtype_jsont_lazy in 179 177 let simple_codec = 180 178 Jsont.map ~kind:"dtype_string" 181 179 ~dec:parse_typestr ··· 188 186 | j -> invalid_arg (Format.asprintf "dtype: expected int in shape, got %a" Jsont.pp_json j)) 189 187 items 190 188 in 191 - (* Decode a single field descriptor from a JSON list: 192 - ["name", "<f4"] or ["name", "<f4", [3, 2]] *) 189 + let decode_nested json = 190 + match Jsont.Json.decode self json with 191 + | Ok v -> v 192 + | Error e -> invalid_arg (Printf.sprintf "dtype: nested structured decode error: %s" e) 193 + in 194 + let encode_nested dt = 195 + match Jsont.Json.encode self dt with 196 + | Ok j -> j 197 + | Error e -> invalid_arg (Printf.sprintf "dtype: encode error: %s" e) 198 + in 193 199 let decode_field (json_items : Jsont.json list) : string * dtype * int list option = 194 200 match json_items with 195 201 | [ Jsont.String (name, _); Jsont.String (typestr, _) ] -> ··· 197 203 | [ Jsont.String (name, _); Jsont.String (typestr, _); Jsont.Array (shape_items, _) ] -> 198 204 (name, parse_typestr typestr, Some (decode_shape shape_items)) 199 205 | [ Jsont.String (name, _); (Jsont.Array _ as nested_json) ] -> 200 - let nested = match Jsont.Json.decode !dtype_jsont_fwd nested_json with 201 - | Ok v -> v 202 - | Error e -> invalid_arg (Printf.sprintf "dtype: nested structured decode error: %s" e) 203 - in 204 - (name, nested, None) 206 + (name, decode_nested nested_json, None) 205 207 | [ Jsont.String (name, _); (Jsont.Array _ as nested_json); Jsont.Array (shape_items, _) ] -> 206 - let nested = match Jsont.Json.decode !dtype_jsont_fwd nested_json with 207 - | Ok v -> v 208 - | Error e -> invalid_arg (Printf.sprintf "dtype: nested structured decode error: %s" e) 209 - in 210 - (name, nested, Some (decode_shape shape_items)) 208 + (name, decode_nested nested_json, Some (decode_shape shape_items)) 211 209 | _ -> invalid_arg "dtype: invalid field descriptor" 212 210 in 213 211 let structured_codec = ··· 223 221 | `Structured fields -> 224 222 List.map (fun (name, dt, shape_opt) -> 225 223 let name_json = Jsont.Json.string name in 226 - let dtype_json = match Jsont.Json.encode !dtype_jsont_fwd dt with 227 - | Ok j -> j 228 - | Error e -> invalid_arg (Printf.sprintf "dtype: encode error: %s" e) 229 - in 224 + let dtype_json = encode_nested dt in 230 225 match shape_opt with 231 226 | None -> Jsont.Json.list [ name_json; dtype_json ] 232 227 | Some shape -> ··· 245 240 | `Structured _ -> structured_codec 246 241 | _ -> simple_codec) 247 242 () 248 - )) 243 + ) 249 244 250 - let () = dtype_jsont_fwd := dtype_jsont 245 + let dtype_jsont : dtype Jsont.t = Jsont.rec' dtype_jsont_lazy 251 246 252 247 module Other_ext = struct 253 248 type t = { name : string; configuration : Jsont.json option; must_understand : bool }