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.

fix: use invalid_arg for bad input instead of failwith

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

+57 -57
+57 -57
src/zarr_jsont.ml
··· 109 109 | '<' -> `Little 110 110 | '>' -> `Big 111 111 | '|' | '=' -> `Not_applicable 112 - | c -> failwith (Printf.sprintf "dtype: unknown endian char %c" c) 112 + | c -> invalid_arg (Printf.sprintf "dtype: unknown endian char %c" c) 113 113 114 114 let endian_char = function 115 115 | `Little -> '<' ··· 119 119 (* Parse a NumPy typestr like "<f8", "|b1", "<M8[ns]", "|S10", etc. *) 120 120 let parse_typestr s = 121 121 if String.length s < 3 then 122 - failwith (Printf.sprintf "dtype: typestr too short: %s" s); 122 + invalid_arg (Printf.sprintf "dtype: typestr too short: %s" s); 123 123 let endian = parse_endian s.[0] in 124 124 let kind = s.[1] in 125 125 let rest = String.sub s 2 (String.length s - 2) in ··· 127 127 | 'b' -> 128 128 let n = int_of_string rest in 129 129 if n = 1 then `Bool 130 - else failwith (Printf.sprintf "dtype: invalid bool size %d" n) 130 + else invalid_arg (Printf.sprintf "dtype: invalid bool size %d" n) 131 131 | 'i' -> `Int (endian, int_of_string rest) 132 132 | 'u' -> `Uint (endian, int_of_string rest) 133 133 | 'f' -> `Float (endian, int_of_string rest) ··· 138 138 if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then begin 139 139 let close = String.index rest ']' in 140 140 String.sub rest 2 (close - 2) 141 - end else failwith (Printf.sprintf "dtype: invalid datetime typestr: %s" s) 141 + end else invalid_arg (Printf.sprintf "dtype: invalid datetime typestr: %s" s) 142 142 in 143 143 `Datetime (endian, unit_str) 144 144 | 'm' -> ··· 146 146 if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then begin 147 147 let close = String.index rest ']' in 148 148 String.sub rest 2 (close - 2) 149 - end else failwith (Printf.sprintf "dtype: invalid timedelta typestr: %s" s) 149 + end else invalid_arg (Printf.sprintf "dtype: invalid timedelta typestr: %s" s) 150 150 in 151 151 `Timedelta (endian, unit_str) 152 152 | 'S' -> `String (int_of_string rest) 153 153 | 'U' -> `Unicode (endian, int_of_string rest) 154 154 | 'V' -> `Raw (int_of_string rest) 155 - | c -> failwith (Printf.sprintf "dtype: unknown kind char %c" c) 155 + | c -> invalid_arg (Printf.sprintf "dtype: unknown kind char %c" c) 156 156 157 157 let encode_typestr (dt : dtype) : string = 158 158 match dt with ··· 166 166 | `String n -> Printf.sprintf "|S%d" n 167 167 | `Unicode (e, n) -> Printf.sprintf "%cU%d" (endian_char e) n 168 168 | `Raw n -> Printf.sprintf "|V%d" n 169 - | `Structured _ -> failwith "dtype: encode_typestr called on structured dtype" 169 + | `Structured _ -> invalid_arg "dtype: encode_typestr called on structured dtype" 170 170 171 171 (* Forward reference to allow recursive dtype_jsont. *) 172 172 let dtype_jsont_fwd : dtype Jsont.t ref = ref (Jsont.todo ~kind:"dtype" ()) ··· 181 181 let decode_shape items = 182 182 List.map (function 183 183 | Jsont.Number (f, _) -> int_of_float f 184 - | j -> failwith (Format.asprintf "dtype: expected int in shape, got %a" Jsont.pp_json j)) 184 + | j -> invalid_arg (Format.asprintf "dtype: expected int in shape, got %a" Jsont.pp_json j)) 185 185 items 186 186 in 187 187 (* Decode a single field descriptor from a JSON list: ··· 195 195 | [ Jsont.String (name, _); (Jsont.Array _ as nested_json) ] -> 196 196 let nested = match Jsont.Json.decode !dtype_jsont_fwd nested_json with 197 197 | Ok v -> v 198 - | Error e -> failwith (Printf.sprintf "dtype: nested structured decode error: %s" e) 198 + | Error e -> invalid_arg (Printf.sprintf "dtype: nested structured decode error: %s" e) 199 199 in 200 200 (name, nested, None) 201 201 | [ Jsont.String (name, _); (Jsont.Array _ as nested_json); Jsont.Array (shape_items, _) ] -> 202 202 let nested = match Jsont.Json.decode !dtype_jsont_fwd nested_json with 203 203 | Ok v -> v 204 - | Error e -> failwith (Printf.sprintf "dtype: nested structured decode error: %s" e) 204 + | Error e -> invalid_arg (Printf.sprintf "dtype: nested structured decode error: %s" e) 205 205 in 206 206 (name, nested, Some (decode_shape shape_items)) 207 - | _ -> failwith "dtype: invalid field descriptor" 207 + | _ -> invalid_arg "dtype: invalid field descriptor" 208 208 in 209 209 let structured_codec = 210 210 Jsont.map ~kind:"dtype_array" 211 211 ~dec:(fun (fields_json : Jsont.json list) -> 212 212 let fields = List.map (function 213 213 | Jsont.Array (items, _) -> decode_field items 214 - | j -> failwith (Format.asprintf "dtype: expected array field descriptor, got %a" Jsont.pp_json j)) 214 + | j -> invalid_arg (Format.asprintf "dtype: expected array field descriptor, got %a" Jsont.pp_json j)) 215 215 fields_json 216 216 in 217 217 `Structured fields) ··· 221 221 let name_json = Jsont.Json.string name in 222 222 let dtype_json = match Jsont.Json.encode !dtype_jsont_fwd dt with 223 223 | Ok j -> j 224 - | Error e -> failwith (Printf.sprintf "dtype: encode error: %s" e) 224 + | Error e -> invalid_arg (Printf.sprintf "dtype: encode error: %s" e) 225 225 in 226 226 match shape_opt with 227 227 | None -> Jsont.Json.list [ name_json; dtype_json ] ··· 364 364 in 365 365 let decode_config codec_t config_json = 366 366 match Jsont.Json.decode codec_t config_json with 367 - | Ok v -> v | Error e -> failwith e 367 + | Ok v -> v | Error e -> invalid_arg e 368 368 in 369 369 let encode_named name config_json = 370 370 let mems = [ (("name", Jsont.Meta.none), Jsont.Json.string name) ] in ··· 376 376 in 377 377 let encode_config codec_t v = 378 378 match Jsont.Json.encode codec_t v with 379 - | Ok j -> j | Error e -> failwith e 379 + | Ok j -> j | Error e -> invalid_arg e 380 380 in 381 381 let index_location_jsont = 382 382 Jsont.enum ~kind:"index_location" ["start", `Start; "end", `End] ··· 407 407 | Jsont.Object (mems, _) -> 408 408 let name = match find_name mems with 409 409 | Some n -> n 410 - | None -> failwith "codec: missing name" 410 + | None -> invalid_arg "codec: missing name" 411 411 in 412 412 let config = find_config mems in 413 413 (match name with ··· 425 425 | _ -> 426 426 (match Jsont.Json.decode Other_ext.jsont json with 427 427 | Ok o -> `Other o 428 - | Error e -> failwith e)) 429 - | _ -> failwith "codec: expected object") 428 + | Error e -> invalid_arg e)) 429 + | _ -> invalid_arg "codec: expected object") 430 430 ~enc:(function 431 431 | `Bytes b -> 432 432 encode_named "bytes" (Some (encode_config Codec.Bytes.jsont b)) ··· 442 442 encode_named "sharding_indexed" (Some (encode_config sharding_config_jsont s)) 443 443 | `Other o -> 444 444 (match Jsont.Json.encode Other_ext.jsont o with 445 - | Ok j -> j | Error e -> failwith e)) 445 + | Ok j -> j | Error e -> invalid_arg e)) 446 446 Jsont.json 447 447 ) 448 448 ··· 462 462 463 463 let decode_config codec_t config_json = 464 464 match Jsont.Json.decode codec_t config_json with 465 - | Ok v -> v | Error e -> failwith e 465 + | Ok v -> v | Error e -> invalid_arg e 466 466 467 467 let encode_named name config_json = 468 468 let mems = [ (("name", Jsont.Meta.none), Jsont.Json.string name) ] in ··· 474 474 475 475 let encode_config codec_t v = 476 476 match Jsont.Json.encode codec_t v with 477 - | Ok j -> j | Error e -> failwith e 477 + | Ok j -> j | Error e -> invalid_arg e 478 478 479 479 let decode_other_ext json = 480 480 match Jsont.Json.decode Other_ext.jsont json with 481 - | Ok o -> o | Error e -> failwith e 481 + | Ok o -> o | Error e -> invalid_arg e 482 482 483 483 let encode_other_ext o = 484 484 match Jsont.Json.encode Other_ext.jsont o with 485 - | Ok j -> j | Error e -> failwith e 485 + | Ok j -> j | Error e -> invalid_arg e 486 486 487 487 module Data_type = struct 488 488 type t = [ ··· 540 540 if String.length s >= 2 && s.[0] = 'r' then 541 541 let bits_str = String.sub s 1 (String.length s - 1) in 542 542 (try `Raw (int_of_string bits_str) 543 - with _ -> failwith (Printf.sprintf "V3.Data_type: unknown type %s" s)) 543 + with _ -> invalid_arg (Printf.sprintf "V3.Data_type: unknown type %s" s)) 544 544 else 545 - failwith (Printf.sprintf "V3.Data_type: unknown type %s" s)) 545 + invalid_arg (Printf.sprintf "V3.Data_type: unknown type %s" s)) 546 546 ~enc:enc_string 547 547 Jsont.string 548 548 in ··· 583 583 | Jsont.Object (mems, _) -> 584 584 let name = match find_name mems with 585 585 | Some n -> n 586 - | None -> failwith "chunk_grid: missing name" 586 + | None -> invalid_arg "chunk_grid: missing name" 587 587 in 588 588 let config = find_config mems in 589 589 (match name with 590 590 | "regular" -> 591 591 `Regular (decode_config Chunk_grid.Regular.jsont (Option.get config)) 592 592 | _ -> `Other (decode_other_ext json)) 593 - | _ -> failwith "chunk_grid: expected object") 593 + | _ -> invalid_arg "chunk_grid: expected object") 594 594 ~enc:(function 595 595 | `Regular r -> 596 596 encode_named "regular" (Some (encode_config Chunk_grid.Regular.jsont r)) ··· 620 620 | Jsont.Object (mems, _) -> 621 621 let name = match find_name mems with 622 622 | Some n -> n 623 - | None -> failwith "chunk_key_encoding: missing name" 623 + | None -> invalid_arg "chunk_key_encoding: missing name" 624 624 in 625 625 let config = find_config mems in 626 626 (match name with 627 627 | "default" -> 628 628 `Default (decode_config Chunk_key_encoding.Default.jsont (Option.get config)) 629 629 | _ -> `Other (decode_other_ext json)) 630 - | _ -> failwith "chunk_key_encoding: expected object") 630 + | _ -> invalid_arg "chunk_key_encoding: expected object") 631 631 ~enc:(function 632 632 | `Default d -> 633 633 encode_named "default" (Some (encode_config Chunk_key_encoding.Default.jsont d)) ··· 766 766 | Some "blosc" -> 767 767 (match Jsont.Json.decode Compressor.Blosc.jsont json with 768 768 | Ok b -> `Blosc b 769 - | Error e -> failwith e) 769 + | Error e -> invalid_arg e) 770 770 | Some "zlib" -> 771 771 (match Jsont.Json.decode Compressor.Zlib.jsont json with 772 772 | Ok z -> `Zlib z 773 - | Error e -> failwith e) 773 + | Error e -> invalid_arg e) 774 774 | _ -> 775 775 (match Jsont.Json.decode Other_codec.jsont json with 776 776 | Ok o -> `Other o 777 - | Error e -> failwith e)) 778 - | _ -> failwith "V2.Compressor: expected object") 777 + | Error e -> invalid_arg e)) 778 + | _ -> invalid_arg "V2.Compressor: expected object") 779 779 ~enc:(function 780 780 | `Blosc b -> 781 781 (match Jsont.Json.encode Compressor.Blosc.jsont b with 782 - | Ok j -> j | Error e -> failwith e) 782 + | Ok j -> j | Error e -> invalid_arg e) 783 783 | `Zlib z -> 784 784 (match Jsont.Json.encode Compressor.Zlib.jsont z with 785 - | Ok j -> j | Error e -> failwith e) 785 + | Ok j -> j | Error e -> invalid_arg e) 786 786 | `Other o -> 787 787 (match Jsont.Json.encode Other_codec.jsont o with 788 - | Ok j -> j | Error e -> failwith e)) 788 + | Ok j -> j | Error e -> invalid_arg e)) 789 789 Jsont.json 790 790 791 791 module Filter = struct ··· 826 826 | Some "delta" -> 827 827 (match Jsont.Json.decode Filter.Delta.jsont json with 828 828 | Ok d -> `Delta d 829 - | Error e -> failwith e) 829 + | Error e -> invalid_arg e) 830 830 | _ -> 831 831 (match Jsont.Json.decode Other_codec.jsont json with 832 832 | Ok o -> `Other o 833 - | Error e -> failwith e)) 834 - | _ -> failwith "V2.Filter: expected object") 833 + | Error e -> invalid_arg e)) 834 + | _ -> invalid_arg "V2.Filter: expected object") 835 835 ~enc:(function 836 836 | `Delta d -> 837 837 (match Jsont.Json.encode Filter.Delta.jsont d with 838 - | Ok j -> j | Error e -> failwith e) 838 + | Ok j -> j | Error e -> invalid_arg e) 839 839 | `Other o -> 840 840 (match Jsont.Json.encode Other_codec.jsont o with 841 - | Ok j -> j | Error e -> failwith e)) 841 + | Ok j -> j | Error e -> invalid_arg e)) 842 842 Jsont.json 843 843 844 844 module Array_meta = struct ··· 1214 1214 ~enc:(fun t -> 1215 1215 match t.V2_node.kind with 1216 1216 | `Array a -> a 1217 - | `Group -> failwith "v2_array_jsont: not an array") 1217 + | `Group -> invalid_arg "v2_array_jsont: not an array") 1218 1218 V2.array_meta_jsont 1219 1219 1220 1220 let v2_group_jsont : V2_node.t Jsont.t = ··· 1239 1239 ~dec:(fun json -> 1240 1240 let mems = match json with 1241 1241 | Jsont.Object (m, _) -> m 1242 - | _ -> failwith "v3_jsont: expected object" 1242 + | _ -> invalid_arg "v3_jsont: expected object" 1243 1243 in 1244 1244 let node_type = match find_mem mems "node_type" with 1245 1245 | Some (Jsont.String (s, _)) -> s 1246 - | _ -> failwith "v3_jsont: missing node_type" 1246 + | _ -> invalid_arg "v3_jsont: missing node_type" 1247 1247 in 1248 1248 let attrs_val = 1249 1249 match find_mem mems "attributes" with ··· 1267 1267 | "array" -> 1268 1268 let arr = match Jsont.Json.decode V3.array_meta_jsont json with 1269 1269 | Ok a -> a 1270 - | Error e -> failwith ("v3_jsont: " ^ e) 1270 + | Error e -> invalid_arg ("v3_jsont: " ^ e) 1271 1271 in 1272 1272 V3_node.{ kind = `Array arr; attrs = attrs_val; unknown = unknown_val } 1273 1273 | "group" -> 1274 1274 V3_node.{ kind = `Group; attrs = attrs_val; unknown = unknown_val } 1275 - | s -> failwith ("v3_jsont: unknown node_type: " ^ s))) 1275 + | s -> invalid_arg ("v3_jsont: unknown node_type: " ^ s))) 1276 1276 ~enc:(fun (t : V3_node.t) -> 1277 1277 let attrs_json = 1278 1278 match Jsont.Json.encode attrs_jsont t.attrs with 1279 1279 | Ok j -> j 1280 - | Error e -> failwith ("v3_jsont enc attrs: " ^ e) 1280 + | Error e -> invalid_arg ("v3_jsont enc attrs: " ^ e) 1281 1281 in 1282 1282 let has_attrs = match attrs_json with 1283 1283 | Jsont.Object ([], _) -> false ··· 1287 1287 | `Array a -> 1288 1288 let arr_json = match Jsont.Json.encode V3.array_meta_jsont a with 1289 1289 | Ok j -> j 1290 - | Error e -> failwith ("v3_jsont enc array: " ^ e) 1290 + | Error e -> invalid_arg ("v3_jsont enc array: " ^ e) 1291 1291 in 1292 1292 let arr_mems = match arr_json with 1293 1293 | Jsont.Object (m, _) -> m ··· 1328 1328 ~dec:(fun json -> 1329 1329 let mems = match json with 1330 1330 | Jsont.Object (m, _) -> m 1331 - | _ -> failwith "jsont: expected object" 1331 + | _ -> invalid_arg "jsont: expected object" 1332 1332 in 1333 1333 let zarr_format = match find_zarr_format mems with 1334 1334 | Some n -> n 1335 - | None -> failwith "jsont: missing zarr_format" 1335 + | None -> invalid_arg "jsont: missing zarr_format" 1336 1336 in 1337 1337 match zarr_format with 1338 1338 | 2 -> 1339 1339 if has_shape mems then 1340 1340 match Jsont.Json.decode v2_array_jsont json with 1341 - | Ok n -> `V2 n | Error e -> failwith e 1341 + | Ok n -> `V2 n | Error e -> invalid_arg e 1342 1342 else 1343 1343 (match Jsont.Json.decode v2_group_jsont json with 1344 - | Ok n -> `V2 n | Error e -> failwith e) 1344 + | Ok n -> `V2 n | Error e -> invalid_arg e) 1345 1345 | 3 -> 1346 1346 (match Jsont.Json.decode v3_jsont json with 1347 - | Ok n -> `V3 n | Error e -> failwith e) 1348 - | n -> failwith (Printf.sprintf "jsont: unknown zarr_format: %d" n)) 1347 + | Ok n -> `V3 n | Error e -> invalid_arg e) 1348 + | n -> invalid_arg (Printf.sprintf "jsont: unknown zarr_format: %d" n)) 1349 1349 ~enc:(function 1350 1350 | `V2 node -> 1351 1351 (match V2_node.kind node with 1352 1352 | `Array _ -> 1353 1353 (match Jsont.Json.encode v2_array_jsont node with 1354 - | Ok j -> j | Error e -> failwith e) 1354 + | Ok j -> j | Error e -> invalid_arg e) 1355 1355 | `Group -> 1356 1356 (match Jsont.Json.encode v2_group_jsont node with 1357 - | Ok j -> j | Error e -> failwith e)) 1357 + | Ok j -> j | Error e -> invalid_arg e)) 1358 1358 | `V3 node -> 1359 1359 (match Jsont.Json.encode v3_jsont node with 1360 - | Ok j -> j | Error e -> failwith e)) 1360 + | Ok j -> j | Error e -> invalid_arg e)) 1361 1361 Jsont.json