···264264 |> Jsont.Object.skip_unknown
265265 |> Jsont.Object.finish
266266end
267267+268268+module V2 = struct
269269+ module Compressor = struct
270270+ module Blosc = struct
271271+ type t = {
272272+ cname : string;
273273+ clevel : int;
274274+ shuffle : int;
275275+ blocksize : int option;
276276+ unknown : Jsont.json;
277277+ }
278278+279279+ let cname t = t.cname
280280+ let clevel t = t.clevel
281281+ let shuffle t = t.shuffle
282282+ let blocksize t = t.blocksize
283283+ let unknown t = t.unknown
284284+285285+ let jsont =
286286+ Jsont.Object.map ~kind:"Blosc"
287287+ (fun _id cname clevel shuffle blocksize unknown ->
288288+ { cname; clevel; shuffle; blocksize; unknown })
289289+ |> Jsont.Object.mem "id" Jsont.string ~enc:(fun _ -> "blosc")
290290+ |> Jsont.Object.mem "cname" Jsont.string ~enc:(fun t -> t.cname)
291291+ |> Jsont.Object.mem "clevel" Jsont.int ~enc:(fun t -> t.clevel)
292292+ |> Jsont.Object.mem "shuffle" Jsont.int ~enc:(fun t -> t.shuffle)
293293+ |> Jsont.Object.opt_mem "blocksize" Jsont.int ~enc:(fun t -> t.blocksize)
294294+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
295295+ |> Jsont.Object.finish
296296+ end
297297+298298+ module Zlib = struct
299299+ type t = {
300300+ level : int;
301301+ unknown : Jsont.json;
302302+ }
303303+304304+ let level t = t.level
305305+ let unknown t = t.unknown
306306+307307+ let jsont =
308308+ Jsont.Object.map ~kind:"Zlib"
309309+ (fun _id level unknown -> { level; unknown })
310310+ |> Jsont.Object.mem "id" Jsont.string ~enc:(fun _ -> "zlib")
311311+ |> Jsont.Object.mem "level" Jsont.int ~enc:(fun t -> t.level)
312312+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
313313+ |> Jsont.Object.finish
314314+ end
315315+ end
316316+317317+ type compressor = [
318318+ | `Blosc of Compressor.Blosc.t
319319+ | `Zlib of Compressor.Zlib.t
320320+ | `Other of Other_codec.t
321321+ ]
322322+323323+ let find_id mems =
324324+ List.find_map (fun ((name, _), value) ->
325325+ if name = "id" then
326326+ match value with
327327+ | Jsont.String (s, _) -> Some s
328328+ | _ -> None
329329+ else None) mems
330330+331331+ let compressor_jsont : compressor Jsont.t =
332332+ Jsont.map ~kind:"V2.Compressor"
333333+ ~dec:(fun json ->
334334+ match json with
335335+ | Jsont.Object (mems, _meta) ->
336336+ let id = find_id mems in
337337+ (match id with
338338+ | Some "blosc" ->
339339+ (match Jsont.Json.decode Compressor.Blosc.jsont json with
340340+ | Ok b -> `Blosc b
341341+ | Error e -> failwith e)
342342+ | Some "zlib" ->
343343+ (match Jsont.Json.decode Compressor.Zlib.jsont json with
344344+ | Ok z -> `Zlib z
345345+ | Error e -> failwith e)
346346+ | _ ->
347347+ (match Jsont.Json.decode Other_codec.jsont json with
348348+ | Ok o -> `Other o
349349+ | Error e -> failwith e))
350350+ | _ -> failwith "V2.Compressor: expected object")
351351+ ~enc:(function
352352+ | `Blosc b ->
353353+ (match Jsont.Json.encode Compressor.Blosc.jsont b with
354354+ | Ok j -> j | Error e -> failwith e)
355355+ | `Zlib z ->
356356+ (match Jsont.Json.encode Compressor.Zlib.jsont z with
357357+ | Ok j -> j | Error e -> failwith e)
358358+ | `Other o ->
359359+ (match Jsont.Json.encode Other_codec.jsont o with
360360+ | Ok j -> j | Error e -> failwith e))
361361+ Jsont.json
362362+363363+ module Filter = struct
364364+ module Delta = struct
365365+ type t = {
366366+ dtype : string;
367367+ astype : string option;
368368+ unknown : Jsont.json;
369369+ }
370370+371371+ let dtype t = t.dtype
372372+ let astype t = t.astype
373373+ let unknown t = t.unknown
374374+375375+ let jsont =
376376+ Jsont.Object.map ~kind:"Delta"
377377+ (fun _id dtype astype unknown -> { dtype; astype; unknown })
378378+ |> Jsont.Object.mem "id" Jsont.string ~enc:(fun _ -> "delta")
379379+ |> Jsont.Object.mem "dtype" Jsont.string ~enc:(fun t -> t.dtype)
380380+ |> Jsont.Object.opt_mem "astype" Jsont.string ~enc:(fun t -> t.astype)
381381+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
382382+ |> Jsont.Object.finish
383383+ end
384384+ end
385385+386386+ type filter = [
387387+ | `Delta of Filter.Delta.t
388388+ | `Other of Other_codec.t
389389+ ]
390390+391391+ let filter_jsont : filter Jsont.t =
392392+ Jsont.map ~kind:"V2.Filter"
393393+ ~dec:(fun json ->
394394+ match json with
395395+ | Jsont.Object (mems, _meta) ->
396396+ let id = find_id mems in
397397+ (match id with
398398+ | Some "delta" ->
399399+ (match Jsont.Json.decode Filter.Delta.jsont json with
400400+ | Ok d -> `Delta d
401401+ | Error e -> failwith e)
402402+ | _ ->
403403+ (match Jsont.Json.decode Other_codec.jsont json with
404404+ | Ok o -> `Other o
405405+ | Error e -> failwith e))
406406+ | _ -> failwith "V2.Filter: expected object")
407407+ ~enc:(function
408408+ | `Delta d ->
409409+ (match Jsont.Json.encode Filter.Delta.jsont d with
410410+ | Ok j -> j | Error e -> failwith e)
411411+ | `Other o ->
412412+ (match Jsont.Json.encode Other_codec.jsont o with
413413+ | Ok j -> j | Error e -> failwith e))
414414+ Jsont.json
415415+end
+53
src/zarr_jsont.mli
···7272 val make : string -> Jsont.json option -> bool -> t
7373 val jsont : t Jsont.t
7474end
7575+7676+(** Zarr v2 compressor and filter codecs. *)
7777+module V2 : sig
7878+ (** Typed sub-codecs for known v2 compressors. *)
7979+ module Compressor : sig
8080+ (** Blosc compressor codec. *)
8181+ module Blosc : sig
8282+ type t
8383+ val cname : t -> string
8484+ val clevel : t -> int
8585+ val shuffle : t -> int
8686+ val blocksize : t -> int option
8787+ val unknown : t -> Jsont.json
8888+ end
8989+9090+ (** Zlib compressor codec. *)
9191+ module Zlib : sig
9292+ type t
9393+ val level : t -> int
9494+ val unknown : t -> Jsont.json
9595+ end
9696+ end
9797+9898+ (** A v2 compressor: either a known type or a catch-all. *)
9999+ type compressor = [
100100+ | `Blosc of Compressor.Blosc.t
101101+ | `Zlib of Compressor.Zlib.t
102102+ | `Other of Other_codec.t
103103+ ]
104104+105105+ val compressor_jsont : compressor Jsont.t
106106+ (** Codec for {!compressor}. Dispatches on the ["id"] field. *)
107107+108108+ (** Typed sub-codecs for known v2 filters. *)
109109+ module Filter : sig
110110+ (** Delta filter codec. *)
111111+ module Delta : sig
112112+ type t
113113+ val dtype : t -> string
114114+ val astype : t -> string option
115115+ val unknown : t -> Jsont.json
116116+ end
117117+ end
118118+119119+ (** A v2 filter: either a known type or a catch-all. *)
120120+ type filter = [
121121+ | `Delta of Filter.Delta.t
122122+ | `Other of Other_codec.t
123123+ ]
124124+125125+ val filter_jsont : filter Jsont.t
126126+ (** Codec for {!filter}. Dispatches on the ["id"] field. *)
127127+end
+44
test/test_zarr_jsont.ml
···107107 assert (decode dt json' = s);
108108 print_endline "test_dtype: ok"
109109110110+let test_v2_compressor () =
111111+ let c = Zarr_jsont.V2.compressor_jsont in
112112+ (* blosc *)
113113+ let json = {|{"id":"blosc","cname":"lz4","clevel":5,"shuffle":1}|} in
114114+ let v = decode c json in
115115+ (match v with
116116+ | `Blosc b ->
117117+ assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4");
118118+ assert (Zarr_jsont.V2.Compressor.Blosc.clevel b = 5);
119119+ assert (Zarr_jsont.V2.Compressor.Blosc.shuffle b = 1)
120120+ | _ -> assert false);
121121+ (* zlib *)
122122+ let json = {|{"id":"zlib","level":1}|} in
123123+ let v = decode c json in
124124+ (match v with
125125+ | `Zlib z -> assert (Zarr_jsont.V2.Compressor.Zlib.level z = 1)
126126+ | _ -> assert false);
127127+ (* unknown compressor *)
128128+ let json = {|{"id":"lzma","preset":6}|} in
129129+ let v = decode c json in
130130+ (match v with
131131+ | `Other o -> assert (Zarr_jsont.Other_codec.name o = "lzma")
132132+ | _ -> assert false);
133133+ print_endline "test_v2_compressor: ok"
134134+135135+let test_v2_filter () =
136136+ let f = Zarr_jsont.V2.filter_jsont in
137137+ let json = {|{"id":"delta","dtype":"<f8","astype":"<f4"}|} in
138138+ let v = decode f json in
139139+ (match v with
140140+ | `Delta d ->
141141+ assert (Zarr_jsont.V2.Filter.Delta.dtype d = "<f8");
142142+ assert (Zarr_jsont.V2.Filter.Delta.astype d = Some "<f4")
143143+ | _ -> assert false);
144144+ (* unknown filter *)
145145+ let json = {|{"id":"quantize","digits":10}|} in
146146+ let v = decode f json in
147147+ (match v with
148148+ | `Other o -> assert (Zarr_jsont.Other_codec.name o = "quantize")
149149+ | _ -> assert false);
150150+ print_endline "test_v2_filter: ok"
151151+110152let () = test_other_codec ()
111153let () = test_other_ext ()
112154let () = test_fill_value ()
113155let () = test_dtype ()
156156+let () = test_v2_compressor ()
157157+let () = test_v2_filter ()