···412412 (match Jsont.Json.encode Other_codec.jsont o with
413413 | Ok j -> j | Error e -> failwith e))
414414 Jsont.json
415415+416416+ module Array_meta = struct
417417+ type t = {
418418+ shape : int list;
419419+ chunks : int list;
420420+ dtype : dtype;
421421+ compressor : compressor option;
422422+ fill_value : fill_value;
423423+ order : [ `C | `F ];
424424+ filters : filter list option;
425425+ dimension_separator : [ `Dot | `Slash ] option;
426426+ unknown : Jsont.json;
427427+ }
428428+ let shape t = t.shape
429429+ let chunks t = t.chunks
430430+ let dtype t = t.dtype
431431+ let compressor t = t.compressor
432432+ let fill_value t = t.fill_value
433433+ let order t = t.order
434434+ let filters t = t.filters
435435+ let dimension_separator t = t.dimension_separator
436436+ let unknown t = t.unknown
437437+ end
438438+439439+ let array_meta_jsont =
440440+ let order_jsont = Jsont.enum ~kind:"order" ["C", `C; "F", `F] in
441441+ let dim_sep_jsont = Jsont.enum ~kind:"dimension_separator" [".", `Dot; "/", `Slash] in
442442+ Jsont.Object.map ~kind:"V2.Array_meta"
443443+ (fun _zarr_format s c d comp fv ord filt dim_sep unk ->
444444+ Array_meta.{ shape = s; chunks = c; dtype = d; compressor = comp; fill_value = fv; order = ord; filters = filt; dimension_separator = dim_sep; unknown = unk })
445445+ |> Jsont.Object.mem "zarr_format" Jsont.int ~enc:(fun _ -> 2)
446446+ |> Jsont.Object.mem "shape" (Jsont.list Jsont.int) ~enc:(fun (t : Array_meta.t) -> t.shape)
447447+ |> Jsont.Object.mem "chunks" (Jsont.list Jsont.int) ~enc:(fun (t : Array_meta.t) -> t.chunks)
448448+ |> Jsont.Object.mem "dtype" dtype_jsont ~enc:(fun (t : Array_meta.t) -> t.dtype)
449449+ |> Jsont.Object.mem "compressor" (Jsont.option compressor_jsont) ~enc:(fun (t : Array_meta.t) -> t.compressor)
450450+ |> Jsont.Object.mem "fill_value" fill_value_jsont ~enc:(fun (t : Array_meta.t) -> t.fill_value)
451451+ |> Jsont.Object.mem "order" order_jsont ~enc:(fun (t : Array_meta.t) -> t.order)
452452+ |> Jsont.Object.mem "filters" (Jsont.option (Jsont.list filter_jsont)) ~enc:(fun (t : Array_meta.t) -> t.filters)
453453+ |> Jsont.Object.opt_mem "dimension_separator" dim_sep_jsont ~enc:(fun (t : Array_meta.t) -> t.dimension_separator)
454454+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (t : Array_meta.t) -> t.unknown)
455455+ |> Jsont.Object.finish
415456end
+19
src/zarr_jsont.mli
···124124125125 val filter_jsont : filter Jsont.t
126126 (** Codec for {!filter}. Dispatches on the ["id"] field. *)
127127+128128+ (** Complete v2 [.zarray] array metadata. *)
129129+ module Array_meta : sig
130130+ type t
131131+ val shape : t -> int list
132132+ val chunks : t -> int list
133133+ val dtype : t -> dtype
134134+ val compressor : t -> compressor option
135135+ val fill_value : t -> fill_value
136136+ val order : t -> [ `C | `F ]
137137+ val filters : t -> filter list option
138138+ val dimension_separator : t -> [ `Dot | `Slash ] option
139139+ val unknown : t -> Jsont.json
140140+ end
141141+142142+ val array_meta_jsont : Array_meta.t Jsont.t
143143+ (** Codec for {!Array_meta.t}. Decodes and encodes the full [.zarray]
144144+ metadata object. The ["zarr_format"] field is consumed on decode and
145145+ always written as [2] on encode. Unknown fields are preserved. *)
127146end
+46
test/test_zarr_jsont.ml
···149149 | _ -> assert false);
150150 print_endline "test_v2_filter: ok"
151151152152+let test_v2_array () =
153153+ let json = {|{
154154+ "zarr_format": 2,
155155+ "shape": [10000, 10000],
156156+ "chunks": [1000, 1000],
157157+ "dtype": "<f8",
158158+ "compressor": {"id": "blosc", "cname": "lz4", "clevel": 5, "shuffle": 1},
159159+ "fill_value": "NaN",
160160+ "order": "C",
161161+ "filters": [{"id": "delta", "dtype": "<f8", "astype": "<f4"}]
162162+ }|} in
163163+ let v = decode Zarr_jsont.V2.array_meta_jsont json in
164164+ assert (Zarr_jsont.V2.Array_meta.shape v = [10000; 10000]);
165165+ assert (Zarr_jsont.V2.Array_meta.chunks v = [1000; 1000]);
166166+ assert (Zarr_jsont.V2.Array_meta.dtype v = `Float (`Little, 8));
167167+ assert (Zarr_jsont.V2.Array_meta.order v = `C);
168168+ (match Zarr_jsont.V2.Array_meta.compressor v with
169169+ | Some (`Blosc b) ->
170170+ assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4")
171171+ | _ -> assert false);
172172+ (match Zarr_jsont.V2.Array_meta.filters v with
173173+ | Some [(`Delta _)] -> ()
174174+ | _ -> assert false);
175175+ (match Zarr_jsont.V2.Array_meta.fill_value v with
176176+ | `Float f -> assert (Float.is_nan f)
177177+ | _ -> assert false);
178178+ (* roundtrip *)
179179+ let json' = encode Zarr_jsont.V2.array_meta_jsont v in
180180+ let _ = decode Zarr_jsont.V2.array_meta_jsont json' in
181181+ (* null compressor and filters *)
182182+ let json2 = {|{
183183+ "zarr_format": 2,
184184+ "shape": [20, 20],
185185+ "chunks": [10, 10],
186186+ "dtype": "<i4",
187187+ "compressor": null,
188188+ "fill_value": 42,
189189+ "order": "C",
190190+ "filters": null
191191+ }|} in
192192+ let v2 = decode Zarr_jsont.V2.array_meta_jsont json2 in
193193+ assert (Zarr_jsont.V2.Array_meta.compressor v2 = None);
194194+ assert (Zarr_jsont.V2.Array_meta.filters v2 = None);
195195+ print_endline "test_v2_array: ok"
196196+152197let () = test_other_codec ()
153198let () = test_other_ext ()
154199let () = test_fill_value ()
155200let () = test_dtype ()
156201let () = test_v2_compressor ()
157202let () = test_v2_filter ()
203203+let () = test_v2_array ()