···99let read_file path =
1010 try
1111 let ic = open_in path in
1212- Fun.protect ~finally:(fun () -> close_in ic) (fun () ->
1313- let n = in_channel_length ic in
1414- let buf = Bytes.create n in
1515- really_input ic buf 0 n;
1616- Ok (Bytes.to_string buf))
1212+ Fun.protect
1313+ ~finally:(fun () -> close_in ic)
1414+ (fun () ->
1515+ let n = in_channel_length ic in
1616+ let buf = Bytes.create n in
1717+ really_input ic buf 0 n;
1818+ Ok (Bytes.to_string buf))
1719 with Sys_error msg -> Error msg
18201921(* HTTP fetching via curl *)
20222123let read_curl url =
2224 let tmp = Filename.temp_file "zarr_inspect" ".json" in
2323- Fun.protect ~finally:(fun () -> Sys.remove tmp) (fun () ->
2424- let cmd = Printf.sprintf "curl -sf -o '%s' '%s'" tmp url in
2525- match Sys.command cmd with
2626- | 0 -> read_file tmp
2727- | _ -> Error (Printf.sprintf "curl failed for %s" url))
2525+ Fun.protect
2626+ ~finally:(fun () -> Sys.remove tmp)
2727+ (fun () ->
2828+ let cmd = Printf.sprintf "curl -sf -o '%s' '%s'" tmp url in
2929+ match Sys.command cmd with
3030+ | 0 -> read_file tmp
3131+ | _ -> Error (Printf.sprintf "curl failed for %s" url))
28322933(* Dispatch: URL or local path *)
30343135let is_url s =
3236 let s = String.lowercase_ascii s in
3333- String.length s > 7 &&
3434- (String.sub s 0 7 = "http://" || String.sub s 0 8 = "https://")
3737+ String.length s > 7
3838+ && (String.sub s 0 7 = "http://" || String.sub s 0 8 = "https://")
35393640let make_reader base_path =
3737- if is_url base_path then
3838- fun relpath -> read_curl (base_path ^ "/" ^ relpath)
3939- else
4040- fun relpath ->
4141- let full = Filename.concat base_path relpath in
4242- read_file full
4141+ if is_url base_path then fun relpath -> read_curl (base_path ^ "/" ^ relpath)
4242+ else fun relpath ->
4343+ let full = Filename.concat base_path relpath in
4444+ read_file full
43454446(* Pretty-print *)
4547···5658 let read = make_reader path in
5759 match Zarr_jsont.probe ~read path with
5860 | Ok result ->
5959- pretty_print_result result;
6060- `Ok ()
6161- | Error msg ->
6262- `Error (false, msg)
6161+ pretty_print_result result;
6262+ `Ok ()
6363+ | Error msg -> `Error (false, msg)
63646465let cmd =
6566 let doc = "Inspect zarr store metadata" in
6666- let man = [
6767- `S Manpage.s_description;
6868- `P "Reads zarr v2 or v3 metadata from a local directory or HTTP URL, \
6969- decodes it using typed codecs, and pretty-prints the re-encoded JSON.";
7070- `S Manpage.s_examples;
7171- `Pre " zarr-inspect ./my-dataset";
7272- `Pre " zarr-inspect https://example.com/zarr-store";
7373- ] in
6767+ let man =
6868+ [
6969+ `S Manpage.s_description;
7070+ `P
7171+ "Reads zarr v2 or v3 metadata from a local directory or HTTP URL, \
7272+ decodes it using typed codecs, and pretty-prints the re-encoded JSON.";
7373+ `S Manpage.s_examples;
7474+ `Pre " zarr-inspect ./my-dataset";
7575+ `Pre " zarr-inspect https://example.com/zarr-store";
7676+ ]
7777+ in
7478 let info = Cmd.info "zarr-inspect" ~version:"0.1.0" ~doc ~man in
7579 Cmd.v info Term.(ret (const run $ path_arg))
7680
+1246-932
src/zarr_jsont.ml
···1818 |> Jsont.Object.finish
1919end
20202121-type fill_value = [
2222- | `Null
2121+type fill_value =
2222+ [ `Null
2323 | `Bool of bool
2424 | `Int of int64
2525 | `Float of float
2626 | `Complex of float * float
2727- | `Bytes of string
2828-]
2727+ | `Bytes of string ]
29283029let fill_value_jsont =
3130 (* Decode a float from a JSON number, deciding if it should be `Int or `Float *)
3231 let dec_number_to_fill f =
3333- if Float.is_finite f && Float.is_integer f && f >= Int64.(to_float min_int) && f <= Int64.(to_float max_int)
3232+ if
3333+ Float.is_finite f && Float.is_integer f
3434+ && (f >= Int64.(to_float min_int))
3535+ && f <= Int64.(to_float max_int)
3436 then `Int (Int64.of_float f)
3537 else `Float f
3638 in
3739 let number_codec =
3838- Jsont.map ~kind:"fill_value_number"
3939- ~dec:dec_number_to_fill
4040+ Jsont.map ~kind:"fill_value_number" ~dec:dec_number_to_fill
4041 ~enc:(function
4141- | `Int i -> Int64.to_float i
4242- | `Float f -> f
4343- | _ -> assert false)
4242+ | `Int i -> Int64.to_float i | `Float f -> f | _ -> assert false)
4443 Jsont.number
4544 in
4645 let string_codec =
4746 Jsont.map ~kind:"fill_value_string"
4848- ~dec:(fun s -> match s with
4747+ ~dec:(fun s ->
4848+ match s with
4949 | "NaN" -> `Float Float.nan
5050 | "Infinity" -> `Float Float.infinity
5151 | "-Infinity" -> `Float Float.neg_infinity
5252- | _ when String.length s > 2 && s.[0] = '0' && (s.[1] = 'x' || s.[1] = 'X') ->
5353- let i = Int64.of_string s in
5454- `Float (Int64.to_float i)
5252+ | _
5353+ when String.length s > 2 && s.[0] = '0' && (s.[1] = 'x' || s.[1] = 'X')
5454+ ->
5555+ let i = Int64.of_string s in
5656+ `Float (Int64.to_float i)
5557 | _ -> `Bytes s)
5658 ~enc:(function
5759 | `Float f when Float.is_nan f -> "NaN"
···6466 (* Array codec: either complex (2 floats) or bytes (list of ints 0-255) *)
6567 let array_codec =
6668 Jsont.map ~kind:"fill_value_array"
6767- ~dec:(fun fs -> match fs with
6868- | [r; i] -> `Complex (r, i)
6969+ ~dec:(fun fs ->
7070+ match fs with
7171+ | [ r; i ] -> `Complex (r, i)
6972 | bs ->
7070- let buf = Bytes.create (List.length bs) in
7171- List.iteri (fun idx b -> Bytes.set buf idx (Char.chr (int_of_float b))) bs;
7272- `Bytes (Bytes.to_string buf))
7373+ let buf = Bytes.create (List.length bs) in
7474+ List.iteri
7575+ (fun idx b -> Bytes.set buf idx (Char.chr (int_of_float b)))
7676+ bs;
7777+ `Bytes (Bytes.to_string buf))
7378 ~enc:(function
7474- | `Complex (r, i) -> [r; i]
7979+ | `Complex (r, i) -> [ r; i ]
7580 | `Bytes s ->
7676- String.to_seq s |> Seq.map (fun c -> float_of_int (Char.code c)) |> List.of_seq
8181+ String.to_seq s
8282+ |> Seq.map (fun c -> float_of_int (Char.code c))
8383+ |> List.of_seq
7784 | _ -> assert false)
7885 (Jsont.list Jsont.number)
7986 in
···8390 ~enc:(function `Bool b -> b | _ -> assert false)
8491 Jsont.bool
8592 in
8686- Jsont.any ~kind:"fill_value"
8787- ~dec_null:(Jsont.null `Null)
8888- ~dec_bool:bool_codec
8989- ~dec_number:number_codec
9090- ~dec_string:string_codec
9191- ~dec_array:array_codec
9393+ Jsont.any ~kind:"fill_value" ~dec_null:(Jsont.null `Null) ~dec_bool:bool_codec
9494+ ~dec_number:number_codec ~dec_string:string_codec ~dec_array:array_codec
9295 ~enc:(function
9396 | `Null -> Jsont.null `Null
9497 | `Bool _ -> bool_codec
···101104102105type endian = [ `Little | `Big | `Not_applicable ]
103106104104-type dtype = [
105105- | `Bool
107107+type dtype =
108108+ [ `Bool
106109 | `Int of endian * int
107110 | `Uint of endian * int
108111 | `Float of endian * int
···112115 | `String of int
113116 | `Unicode of endian * int
114117 | `Raw of int
115115- | `Structured of (string * dtype * int list option) list
116116-]
118118+ | `Structured of (string * dtype * int list option) list ]
117119118120let parse_endian c =
119121 match c with
···123125 | c -> Error (Printf.sprintf "unknown endian char '%c'" c)
124126125127let endian_char = function
126126- | `Little -> '<' | `Big -> '>' | `Not_applicable -> '|'
128128+ | `Little -> '<'
129129+ | `Big -> '>'
130130+ | `Not_applicable -> '|'
127131128132let parse_typestr s : (dtype, string) result =
129133 if String.length s < 3 then Error (Printf.sprintf "typestr too short: %s" s)
130134 else
131135 match parse_endian s.[0] with
132136 | Error _ as e -> e
133133- | Ok endian ->
134134- let kind = s.[1] in
135135- let rest = String.sub s 2 (String.length s - 2) in
136136- match kind with
137137- | 'b' ->
138138- let n = int_of_string rest in
139139- if n = 1 then Ok `Bool
140140- else Error (Printf.sprintf "invalid bool size %d" n)
141141- | 'i' -> Ok (`Int (endian, int_of_string rest))
142142- | 'u' -> Ok (`Uint (endian, int_of_string rest))
143143- | 'f' -> Ok (`Float (endian, int_of_string rest))
144144- | 'c' -> Ok (`Complex (endian, int_of_string rest))
145145- | 'M' ->
146146- if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then
147147- let close = String.index rest ']' in
148148- Ok (`Datetime (endian, String.sub rest 2 (close - 2)))
149149- else Error (Printf.sprintf "invalid datetime typestr: %s" s)
150150- | 'm' ->
151151- if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then
152152- let close = String.index rest ']' in
153153- Ok (`Timedelta (endian, String.sub rest 2 (close - 2)))
154154- else Error (Printf.sprintf "invalid timedelta typestr: %s" s)
155155- | 'S' -> Ok (`String (int_of_string rest))
156156- | 'U' -> Ok (`Unicode (endian, int_of_string rest))
157157- | 'V' -> Ok (`Raw (int_of_string rest))
158158- | c -> Error (Printf.sprintf "unknown dtype kind '%c'" c)
137137+ | Ok endian -> (
138138+ let kind = s.[1] in
139139+ let rest = String.sub s 2 (String.length s - 2) in
140140+ match kind with
141141+ | 'b' ->
142142+ let n = int_of_string rest in
143143+ if n = 1 then Ok `Bool
144144+ else Error (Printf.sprintf "invalid bool size %d" n)
145145+ | 'i' -> Ok (`Int (endian, int_of_string rest))
146146+ | 'u' -> Ok (`Uint (endian, int_of_string rest))
147147+ | 'f' -> Ok (`Float (endian, int_of_string rest))
148148+ | 'c' -> Ok (`Complex (endian, int_of_string rest))
149149+ | 'M' ->
150150+ if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then
151151+ let close = String.index rest ']' in
152152+ Ok (`Datetime (endian, String.sub rest 2 (close - 2)))
153153+ else Error (Printf.sprintf "invalid datetime typestr: %s" s)
154154+ | 'm' ->
155155+ if String.length rest > 2 && rest.[0] = '8' && rest.[1] = '[' then
156156+ let close = String.index rest ']' in
157157+ Ok (`Timedelta (endian, String.sub rest 2 (close - 2)))
158158+ else Error (Printf.sprintf "invalid timedelta typestr: %s" s)
159159+ | 'S' -> Ok (`String (int_of_string rest))
160160+ | 'U' -> Ok (`Unicode (endian, int_of_string rest))
161161+ | 'V' -> Ok (`Raw (int_of_string rest))
162162+ | c -> Error (Printf.sprintf "unknown dtype kind '%c'" c))
159163160164let encode_typestr (dt : dtype) : string =
161165 match dt with
···173177174178(* Helpers for using Jsont codecs inside ~dec/~enc functions.
175179 These raise Jsont.Error on failure, which the framework catches. *)
176176-let jdec codec json = match Jsont.Json.decode codec json with
177177- | Ok v -> v | Error e -> Jsont.Error.msg Jsont.Meta.none e
180180+let jdec codec json =
181181+ match Jsont.Json.decode codec json with
182182+ | Ok v -> v
183183+ | Error e -> Jsont.Error.msg Jsont.Meta.none e
178184179179-let jenc codec v = match Jsont.Json.encode codec v with
180180- | Ok j -> j | Error e -> Jsont.Error.msg Jsont.Meta.none e
185185+let jenc codec v =
186186+ match Jsont.Json.encode codec v with
187187+ | Ok j -> j
188188+ | Error e -> Jsont.Error.msg Jsont.Meta.none e
181189182182-let rec dtype_jsont_lazy : dtype Jsont.t Lazy.t = lazy (
183183- let self = Jsont.rec' dtype_jsont_lazy in
184184- let simple_codec =
185185- Jsont.of_of_string ~kind:"dtype" parse_typestr ~enc:encode_typestr
186186- in
187187- (* A structured field is a JSON array: ["name", dtype] or ["name", dtype, [shape]] *)
188188- let field_jsont =
189189- Jsont.map ~kind:"dtype_field"
190190- ~dec:(fun items ->
191191- let n = List.length items in
192192- if n < 2 then
193193- Jsont.Error.msgf Jsont.Meta.none "dtype field: need at least 2 elements";
194194- let name = jdec Jsont.string (List.nth items 0) in
195195- let dt = jdec self (List.nth items 1) in
196196- let shape =
197197- if n >= 3 then Some (jdec (Jsont.list Jsont.int) (List.nth items 2))
198198- else None
199199- in
200200- (name, dt, shape))
201201- ~enc:(fun (name, dt, shape) ->
202202- let elts = [ Jsont.Json.string name; jenc self dt ] in
203203- match shape with
204204- | None -> elts
205205- | Some s -> elts @ [ jenc (Jsont.list Jsont.int) s ])
206206- (Jsont.list Jsont.json)
207207- in
208208- let structured_codec =
209209- Jsont.map ~kind:"dtype"
210210- ~dec:(fun fields -> `Structured fields)
211211- ~enc:(function `Structured fields -> fields | _ -> assert false)
212212- (Jsont.list field_jsont)
213213- in
214214- Jsont.any ~kind:"dtype"
215215- ~dec_string:simple_codec
216216- ~dec_array:structured_codec
217217- ~enc:(function
218218- | `Structured _ -> structured_codec
219219- | _ -> simple_codec)
220220- ()
221221-)
190190+let rec dtype_jsont_lazy : dtype Jsont.t Lazy.t =
191191+ lazy
192192+ (let self = Jsont.rec' dtype_jsont_lazy in
193193+ let simple_codec =
194194+ Jsont.of_of_string ~kind:"dtype" parse_typestr ~enc:encode_typestr
195195+ in
196196+ (* A structured field is a JSON array: ["name", dtype] or ["name", dtype, [shape]] *)
197197+ let field_jsont =
198198+ Jsont.map ~kind:"dtype_field"
199199+ ~dec:(fun items ->
200200+ let n = List.length items in
201201+ if n < 2 then
202202+ Jsont.Error.msgf Jsont.Meta.none
203203+ "dtype field: need at least 2 elements";
204204+ let name = jdec Jsont.string (List.nth items 0) in
205205+ let dt = jdec self (List.nth items 1) in
206206+ let shape =
207207+ if n >= 3 then
208208+ Some (jdec (Jsont.list Jsont.int) (List.nth items 2))
209209+ else None
210210+ in
211211+ (name, dt, shape))
212212+ ~enc:(fun (name, dt, shape) ->
213213+ let elts = [ Jsont.Json.string name; jenc self dt ] in
214214+ match shape with
215215+ | None -> elts
216216+ | Some s -> elts @ [ jenc (Jsont.list Jsont.int) s ])
217217+ (Jsont.list Jsont.json)
218218+ in
219219+ let structured_codec =
220220+ Jsont.map ~kind:"dtype"
221221+ ~dec:(fun fields -> `Structured fields)
222222+ ~enc:(function `Structured fields -> fields | _ -> assert false)
223223+ (Jsont.list field_jsont)
224224+ in
225225+ Jsont.any ~kind:"dtype" ~dec_string:simple_codec
226226+ ~dec_array:structured_codec
227227+ ~enc:(function `Structured _ -> structured_codec | _ -> simple_codec)
228228+ ())
222229223230let dtype_jsont : dtype Jsont.t = Jsont.rec' dtype_jsont_lazy
224231225232module Other_ext = struct
226226- type t = { name : string; configuration : Jsont.json option; must_understand : bool }
233233+ type t = {
234234+ name : string;
235235+ configuration : Jsont.json option;
236236+ must_understand : bool;
237237+ }
227238228239 let name e = e.name
229240 let configuration e = e.configuration
230241 let must_understand e = e.must_understand
231231- let make name configuration must_understand = { name; configuration; must_understand }
242242+243243+ let make name configuration must_understand =
244244+ { name; configuration; must_understand }
232245233246 let jsont =
234247 Jsont.Object.map ~kind:"Other_ext" make
235248 |> Jsont.Object.mem "name" Jsont.string ~enc:name
236249 |> Jsont.Object.opt_mem "configuration" Jsont.json ~enc:configuration
237237- |> Jsont.Object.mem "must_understand" Jsont.bool
238238- ~dec_absent:true
250250+ |> Jsont.Object.mem "must_understand" Jsont.bool ~dec_absent:true
239251 ~enc_omit:(fun v -> v)
240252 ~enc:must_understand
241241- |> Jsont.Object.skip_unknown
242242- |> Jsont.Object.finish
253253+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
243254end
244255245256module V3 = struct
246257 module Codec = struct
247258 module Bytes = struct
248259 type t = { endian : [ `Little | `Big ] option }
260260+249261 let endian t = t.endian
250250- let endian_jsont = Jsont.enum ~kind:"endian" ["little", `Little; "big", `Big]
262262+263263+ let endian_jsont =
264264+ Jsont.enum ~kind:"endian" [ ("little", `Little); ("big", `Big) ]
265265+251266 let jsont =
252267 Jsont.Object.map ~kind:"Bytes.config" (fun e -> { endian = e })
253268 |> Jsont.Object.opt_mem "endian" endian_jsont ~enc:(fun t -> t.endian)
254254- |> Jsont.Object.skip_unknown
255255- |> Jsont.Object.finish
269269+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
256270 end
257271258272 module Gzip = struct
259273 type t = { level : int }
274274+260275 let level t = t.level
276276+261277 let jsont =
262278 Jsont.Object.map ~kind:"Gzip.config" (fun l -> { level = l })
263279 |> Jsont.Object.mem "level" Jsont.int ~enc:(fun t -> t.level)
264264- |> Jsont.Object.skip_unknown
265265- |> Jsont.Object.finish
280280+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
266281 end
267282268283 module Blosc = struct
···273288 typesize : int option;
274289 blocksize : int;
275290 }
291291+276292 let cname t = t.cname
277293 let clevel t = t.clevel
278294 let shuffle t = t.shuffle
279295 let typesize t = t.typesize
280296 let blocksize t = t.blocksize
281281- let shuffle_jsont = Jsont.enum ~kind:"blosc_shuffle"
282282- ["noshuffle", `Noshuffle; "shuffle", `Shuffle; "bitshuffle", `Bitshuffle]
297297+298298+ let shuffle_jsont =
299299+ Jsont.enum ~kind:"blosc_shuffle"
300300+ [
301301+ ("noshuffle", `Noshuffle);
302302+ ("shuffle", `Shuffle);
303303+ ("bitshuffle", `Bitshuffle);
304304+ ]
305305+283306 let jsont =
284284- Jsont.Object.map ~kind:"Blosc.config"
285285- (fun cn cl sh ts bs -> { cname = cn; clevel = cl; shuffle = sh; typesize = ts; blocksize = bs })
307307+ Jsont.Object.map ~kind:"Blosc.config" (fun cn cl sh ts bs ->
308308+ {
309309+ cname = cn;
310310+ clevel = cl;
311311+ shuffle = sh;
312312+ typesize = ts;
313313+ blocksize = bs;
314314+ })
286315 |> Jsont.Object.mem "cname" Jsont.string ~enc:(fun t -> t.cname)
287316 |> Jsont.Object.mem "clevel" Jsont.int ~enc:(fun t -> t.clevel)
288317 |> Jsont.Object.mem "shuffle" shuffle_jsont ~enc:(fun t -> t.shuffle)
289318 |> Jsont.Object.opt_mem "typesize" Jsont.int ~enc:(fun t -> t.typesize)
290319 |> Jsont.Object.mem "blocksize" Jsont.int ~enc:(fun t -> t.blocksize)
291291- |> Jsont.Object.skip_unknown
292292- |> Jsont.Object.finish
320320+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
293321 end
294322295323 module Transpose = struct
296324 type t = { order : int list }
325325+297326 let order t = t.order
327327+298328 let jsont =
299329 Jsont.Object.map ~kind:"Transpose.config" (fun o -> { order = o })
300300- |> Jsont.Object.mem "order" (Jsont.list Jsont.int) ~enc:(fun t -> t.order)
301301- |> Jsont.Object.skip_unknown
302302- |> Jsont.Object.finish
330330+ |> Jsont.Object.mem "order" (Jsont.list Jsont.int) ~enc:(fun t ->
331331+ t.order)
332332+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
303333 end
304334305335 module Sharding = struct
···309339 index_codecs : codec list;
310340 index_location : [ `Start | `End ];
311341 }
312312- and codec = [
313313- | `Bytes of Bytes.t
342342+343343+ and codec =
344344+ [ `Bytes of Bytes.t
314345 | `Gzip of Gzip.t
315346 | `Blosc of Blosc.t
316347 | `Crc32c
317348 | `Transpose of Transpose.t
318349 | `Sharding of t
319319- | `Other of Other_ext.t
320320- ]
350350+ | `Other of Other_ext.t ]
351351+321352 let chunk_shape t = t.chunk_shape
322353 let codecs t = t.codecs
323354 let index_codecs t = t.index_codecs
···329360330361 (* Shared helpers for name-dispatched object codecs *)
331362 let find_name mems =
332332- List.find_map (fun ((name, _), value) ->
333333- if name = "name" then match value with
334334- | Jsont.String (s, _) -> Some s
335335- | _ -> None
336336- else None) mems
363363+ List.find_map
364364+ (fun ((name, _), value) ->
365365+ if name = "name" then
366366+ match value with Jsont.String (s, _) -> Some s | _ -> None
367367+ else None)
368368+ mems
337369338370 let find_config mems =
339339- List.find_map (fun ((name, _), value) ->
340340- if name = "configuration" then Some value else None) mems
371371+ List.find_map
372372+ (fun ((name, _), value) ->
373373+ if name = "configuration" then Some value else None)
374374+ mems
341375342376 let decode_config codec_t config_json = jdec codec_t config_json
343377344378 let encode_named name config_json =
345379 let mems = [ (("name", Jsont.Meta.none), Jsont.Json.string name) ] in
346346- let mems = match config_json with
380380+ let mems =
381381+ match config_json with
347382 | None -> mems
348383 | Some c -> mems @ [ (("configuration", Jsont.Meta.none), c) ]
349384 in
350385 Jsont.Json.object' mems
351386352387 let encode_config codec_t v = jenc codec_t v
353353-354388 let decode_other_ext json = jdec Other_ext.jsont json
355355-356389 let encode_other_ext o = jenc Other_ext.jsont o
357390358391 let name_dispatch ~kind cases json =
359392 match json with
360360- | Jsont.Object (mems, _) ->
361361- let name = match find_name mems with
362362- | Some n -> n | None -> Jsont.Error.msgf Jsont.Meta.none "%s: missing name" kind
363363- in
364364- let config = match find_config mems with
365365- | Some c -> c | None -> Jsont.Json.object' []
366366- in
367367- (match List.assoc_opt name cases with
368368- | Some codec -> jdec codec config
369369- | None -> `Other (jdec Other_ext.jsont json))
393393+ | Jsont.Object (mems, _) -> (
394394+ let name =
395395+ match find_name mems with
396396+ | Some n -> n
397397+ | None -> Jsont.Error.msgf Jsont.Meta.none "%s: missing name" kind
398398+ in
399399+ let config =
400400+ match find_config mems with
401401+ | Some c -> c
402402+ | None -> Jsont.Json.object' []
403403+ in
404404+ match List.assoc_opt name cases with
405405+ | Some codec -> jdec codec config
406406+ | None -> `Other (jdec Other_ext.jsont json))
370407 | _ -> Jsont.Error.msgf Jsont.Meta.none "%s: expected object" kind
371408372372- let rec codec_jsont_lazy : codec Jsont.t Lazy.t = lazy (
373373- let index_location_jsont =
374374- Jsont.enum ~kind:"index_location" ["start", `Start; "end", `End]
375375- in
376376- let sharding_config_jsont =
377377- let codec_list = Jsont.list (Jsont.rec' codec_jsont_lazy) in
378378- Jsont.Object.map ~kind:"Sharding.config"
379379- (fun cs cc ic il ->
380380- Codec.Sharding.{ chunk_shape = cs; codecs = cc; index_codecs = ic; index_location = il })
381381- |> Jsont.Object.mem "chunk_shape" (Jsont.list Jsont.int)
382382- ~enc:(fun (t : Codec.Sharding.t) -> t.chunk_shape)
383383- |> Jsont.Object.mem "codecs" codec_list
384384- ~enc:(fun (t : Codec.Sharding.t) -> t.codecs)
385385- |> Jsont.Object.mem "index_codecs" codec_list
386386- ~dec_absent:[]
387387- ~enc:(fun (t : Codec.Sharding.t) -> t.index_codecs)
388388- ~enc_omit:(fun l -> l = [])
389389- |> Jsont.Object.mem "index_location" index_location_jsont
390390- ~dec_absent:`End
391391- ~enc:(fun (t : Codec.Sharding.t) -> t.index_location)
392392- ~enc_omit:(fun v -> v = `End)
393393- |> Jsont.Object.skip_unknown
394394- |> Jsont.Object.finish
395395- in
396396- Jsont.map ~kind:"V3.Codec"
397397- ~dec:(fun json ->
398398- match json with
399399- | Jsont.Object (mems, _) ->
400400- let name = match find_name mems with
401401- | Some n -> n
402402- | None -> Jsont.Error.msgf Jsont.Meta.none "codec: missing name"
403403- in
404404- let config = find_config mems in
405405- let config_or_empty = match config with
406406- | Some c -> c | None -> Jsont.Json.object' []
407407- in
408408- (match name with
409409- | "bytes" ->
410410- `Bytes (decode_config Codec.Bytes.jsont config_or_empty)
411411- | "gzip" ->
412412- `Gzip (decode_config Codec.Gzip.jsont config_or_empty)
413413- | "blosc" ->
414414- `Blosc (decode_config Codec.Blosc.jsont config_or_empty)
415415- | "crc32c" -> `Crc32c
416416- | "transpose" ->
417417- `Transpose (decode_config Codec.Transpose.jsont config_or_empty)
418418- | "sharding_indexed" ->
419419- `Sharding (decode_config sharding_config_jsont config_or_empty)
420420- | _ -> `Other (decode_other_ext json))
421421- | _ -> Jsont.Error.msgf Jsont.Meta.none "codec: expected object")
422422- ~enc:(function
423423- | `Bytes b ->
424424- encode_named "bytes" (Some (encode_config Codec.Bytes.jsont b))
425425- | `Gzip g ->
426426- encode_named "gzip" (Some (encode_config Codec.Gzip.jsont g))
427427- | `Blosc b ->
428428- encode_named "blosc" (Some (encode_config Codec.Blosc.jsont b))
429429- | `Crc32c ->
430430- encode_named "crc32c" None
431431- | `Transpose t ->
432432- encode_named "transpose" (Some (encode_config Codec.Transpose.jsont t))
433433- | `Sharding s ->
434434- encode_named "sharding_indexed" (Some (encode_config sharding_config_jsont s))
435435- | `Other o -> encode_other_ext o)
436436- Jsont.json
437437- )
409409+ let rec codec_jsont_lazy : codec Jsont.t Lazy.t =
410410+ lazy
411411+ (let index_location_jsont =
412412+ Jsont.enum ~kind:"index_location" [ ("start", `Start); ("end", `End) ]
413413+ in
414414+ let sharding_config_jsont =
415415+ let codec_list = Jsont.list (Jsont.rec' codec_jsont_lazy) in
416416+ Jsont.Object.map ~kind:"Sharding.config" (fun cs cc ic il ->
417417+ Codec.Sharding.
418418+ {
419419+ chunk_shape = cs;
420420+ codecs = cc;
421421+ index_codecs = ic;
422422+ index_location = il;
423423+ })
424424+ |> Jsont.Object.mem "chunk_shape" (Jsont.list Jsont.int)
425425+ ~enc:(fun (t : Codec.Sharding.t) -> t.chunk_shape)
426426+ |> Jsont.Object.mem "codecs" codec_list
427427+ ~enc:(fun (t : Codec.Sharding.t) -> t.codecs)
428428+ |> Jsont.Object.mem "index_codecs" codec_list ~dec_absent:[]
429429+ ~enc:(fun (t : Codec.Sharding.t) -> t.index_codecs)
430430+ ~enc_omit:(fun l -> l = [])
431431+ |> Jsont.Object.mem "index_location" index_location_jsont
432432+ ~dec_absent:`End
433433+ ~enc:(fun (t : Codec.Sharding.t) -> t.index_location)
434434+ ~enc_omit:(fun v -> v = `End)
435435+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
436436+ in
437437+ Jsont.map ~kind:"V3.Codec"
438438+ ~dec:(fun json ->
439439+ match json with
440440+ | Jsont.Object (mems, _) -> (
441441+ let name =
442442+ match find_name mems with
443443+ | Some n -> n
444444+ | None ->
445445+ Jsont.Error.msgf Jsont.Meta.none "codec: missing name"
446446+ in
447447+ let config = find_config mems in
448448+ let config_or_empty =
449449+ match config with Some c -> c | None -> Jsont.Json.object' []
450450+ in
451451+ match name with
452452+ | "bytes" ->
453453+ `Bytes (decode_config Codec.Bytes.jsont config_or_empty)
454454+ | "gzip" ->
455455+ `Gzip (decode_config Codec.Gzip.jsont config_or_empty)
456456+ | "blosc" ->
457457+ `Blosc (decode_config Codec.Blosc.jsont config_or_empty)
458458+ | "crc32c" -> `Crc32c
459459+ | "transpose" ->
460460+ `Transpose
461461+ (decode_config Codec.Transpose.jsont config_or_empty)
462462+ | "sharding_indexed" ->
463463+ `Sharding
464464+ (decode_config sharding_config_jsont config_or_empty)
465465+ | _ -> `Other (decode_other_ext json))
466466+ | _ -> Jsont.Error.msgf Jsont.Meta.none "codec: expected object")
467467+ ~enc:(function
468468+ | `Bytes b ->
469469+ encode_named "bytes" (Some (encode_config Codec.Bytes.jsont b))
470470+ | `Gzip g ->
471471+ encode_named "gzip" (Some (encode_config Codec.Gzip.jsont g))
472472+ | `Blosc b ->
473473+ encode_named "blosc" (Some (encode_config Codec.Blosc.jsont b))
474474+ | `Crc32c -> encode_named "crc32c" None
475475+ | `Transpose t ->
476476+ encode_named "transpose"
477477+ (Some (encode_config Codec.Transpose.jsont t))
478478+ | `Sharding s ->
479479+ encode_named "sharding_indexed"
480480+ (Some (encode_config sharding_config_jsont s))
481481+ | `Other o -> encode_other_ext o)
482482+ Jsont.json)
438483439484 let codec_jsont : codec Jsont.t = Jsont.rec' codec_jsont_lazy
440485441486 module Data_type = struct
442442- type t = [
443443- | `Bool | `Int8 | `Int16 | `Int32 | `Int64
444444- | `Uint8 | `Uint16 | `Uint32 | `Uint64
445445- | `Float16 | `Float32 | `Float64
446446- | `Complex64 | `Complex128
487487+ type t =
488488+ [ `Bool
489489+ | `Int8
490490+ | `Int16
491491+ | `Int32
492492+ | `Int64
493493+ | `Uint8
494494+ | `Uint16
495495+ | `Uint32
496496+ | `Uint64
497497+ | `Float16
498498+ | `Float32
499499+ | `Float64
500500+ | `Complex64
501501+ | `Complex128
447502 | `Raw of int
448448- | `Other of Other_ext.t
449449- ]
503503+ | `Other of Other_ext.t ]
450504 end
451505452506 let data_type_jsont : Data_type.t Jsont.t =
453453- let string_table = [
454454- "bool", (`Bool : Data_type.t);
455455- "int8", `Int8;
456456- "int16", `Int16;
457457- "int32", `Int32;
458458- "int64", `Int64;
459459- "uint8", `Uint8;
460460- "uint16", `Uint16;
461461- "uint32", `Uint32;
462462- "uint64", `Uint64;
463463- "float16", `Float16;
464464- "float32", `Float32;
465465- "float64", `Float64;
466466- "complex64", `Complex64;
467467- "complex128", `Complex128;
468468- ] in
507507+ let string_table =
508508+ [
509509+ ("bool", (`Bool : Data_type.t));
510510+ ("int8", `Int8);
511511+ ("int16", `Int16);
512512+ ("int32", `Int32);
513513+ ("int64", `Int64);
514514+ ("uint8", `Uint8);
515515+ ("uint16", `Uint16);
516516+ ("uint32", `Uint32);
517517+ ("uint64", `Uint64);
518518+ ("float16", `Float16);
519519+ ("float32", `Float32);
520520+ ("float64", `Float64);
521521+ ("complex64", `Complex64);
522522+ ("complex128", `Complex128);
523523+ ]
524524+ in
469525 let enc_string : Data_type.t -> string = function
470470- | `Bool -> "bool"
471471- | `Int8 -> "int8"
472472- | `Int16 -> "int16"
473473- | `Int32 -> "int32"
474474- | `Int64 -> "int64"
475475- | `Uint8 -> "uint8"
476476- | `Uint16 -> "uint16"
477477- | `Uint32 -> "uint32"
478478- | `Uint64 -> "uint64"
479479- | `Float16 -> "float16"
480480- | `Float32 -> "float32"
481481- | `Float64 -> "float64"
482482- | `Complex64 -> "complex64"
526526+ | `Bool -> "bool"
527527+ | `Int8 -> "int8"
528528+ | `Int16 -> "int16"
529529+ | `Int32 -> "int32"
530530+ | `Int64 -> "int64"
531531+ | `Uint8 -> "uint8"
532532+ | `Uint16 -> "uint16"
533533+ | `Uint32 -> "uint32"
534534+ | `Uint64 -> "uint64"
535535+ | `Float16 -> "float16"
536536+ | `Float32 -> "float32"
537537+ | `Float64 -> "float64"
538538+ | `Complex64 -> "complex64"
483539 | `Complex128 -> "complex128"
484484- | `Raw n -> Printf.sprintf "r%d" n
485485- | `Other _ -> assert false
540540+ | `Raw n -> Printf.sprintf "r%d" n
541541+ | `Other _ -> assert false
486542 in
487543 let dec_string =
488544 Jsont.map ~kind:"V3.Data_type.string"
···490546 match List.assoc_opt s string_table with
491547 | Some v -> v
492548 | None ->
493493- (* Check for r<bits> raw type *)
494494- if String.length s >= 2 && s.[0] = 'r' then
495495- let bits_str = String.sub s 1 (String.length s - 1) in
496496- (try `Raw (int_of_string bits_str)
497497- with _ -> Jsont.Error.msgf Jsont.Meta.none "V3.Data_type: unknown type %s" s)
498498- else
499499- Jsont.Error.msgf Jsont.Meta.none "V3.Data_type: unknown type %s" s)
500500- ~enc:enc_string
501501- Jsont.string
549549+ (* Check for r<bits> raw type *)
550550+ if String.length s >= 2 && s.[0] = 'r' then
551551+ let bits_str = String.sub s 1 (String.length s - 1) in
552552+ try `Raw (int_of_string bits_str)
553553+ with _ ->
554554+ Jsont.Error.msgf Jsont.Meta.none
555555+ "V3.Data_type: unknown type %s" s
556556+ else
557557+ Jsont.Error.msgf Jsont.Meta.none "V3.Data_type: unknown type %s"
558558+ s)
559559+ ~enc:enc_string Jsont.string
502560 in
503561 let dec_object =
504562 Jsont.map ~kind:"V3.Data_type.object"
505563 ~dec:(fun json -> `Other (decode_other_ext json))
506506- ~enc:(function
507507- | `Other o -> encode_other_ext o
508508- | _ -> assert false)
564564+ ~enc:(function `Other o -> encode_other_ext o | _ -> assert false)
509565 Jsont.json
510566 in
511511- Jsont.any ~kind:"V3.Data_type"
512512- ~dec_string
513513- ~dec_object
514514- ~enc:(function
515515- | `Other _ -> dec_object
516516- | _ -> dec_string)
567567+ Jsont.any ~kind:"V3.Data_type" ~dec_string ~dec_object
568568+ ~enc:(function `Other _ -> dec_object | _ -> dec_string)
517569 ()
518570519571 module Chunk_grid = struct
520572 module Regular = struct
521573 type t = { chunk_shape : int list }
574574+522575 let chunk_shape t = t.chunk_shape
576576+523577 let jsont =
524578 Jsont.Object.map ~kind:"Regular.config" (fun cs -> { chunk_shape = cs })
525525- |> Jsont.Object.mem "chunk_shape" (Jsont.list Jsont.int) ~enc:(fun t -> t.chunk_shape)
526526- |> Jsont.Object.skip_unknown
527527- |> Jsont.Object.finish
579579+ |> Jsont.Object.mem "chunk_shape" (Jsont.list Jsont.int) ~enc:(fun t ->
580580+ t.chunk_shape)
581581+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
528582 end
529583530584 type t = [ `Regular of Regular.t | `Other of Other_ext.t ]
531585 end
532586533587 let chunk_grid_jsont : Chunk_grid.t Jsont.t =
534534- let regular_codec = Jsont.map ~kind:"regular_grid"
535535- ~dec:(fun r -> `Regular r)
536536- ~enc:(function `Regular r -> r | _ -> assert false)
537537- Chunk_grid.Regular.jsont
588588+ let regular_codec =
589589+ Jsont.map ~kind:"regular_grid"
590590+ ~dec:(fun r -> `Regular r)
591591+ ~enc:(function `Regular r -> r | _ -> assert false)
592592+ Chunk_grid.Regular.jsont
538593 in
539594 Jsont.map ~kind:"V3.Chunk_grid"
540540- ~dec:(fun json -> name_dispatch ~kind:"chunk_grid" ["regular", regular_codec] json)
595595+ ~dec:(fun json ->
596596+ name_dispatch ~kind:"chunk_grid" [ ("regular", regular_codec) ] json)
541597 ~enc:(function
542598 | `Regular r ->
543543- encode_named "regular" (Some (encode_config Chunk_grid.Regular.jsont r))
599599+ encode_named "regular"
600600+ (Some (encode_config Chunk_grid.Regular.jsont r))
544601 | `Other o -> encode_other_ext o)
545602 Jsont.json
546603547604 module Chunk_key_encoding = struct
548605 module Default = struct
549606 type t = { separator : [ `Slash | `Dot ] }
607607+550608 let separator t = t.separator
609609+551610 let separator_jsont =
552552- Jsont.enum ~kind:"separator" ["/", `Slash; ".", `Dot]
611611+ Jsont.enum ~kind:"separator" [ ("/", `Slash); (".", `Dot) ]
612612+553613 let jsont =
554614 Jsont.Object.map ~kind:"Default.config" (fun sep -> { separator = sep })
555555- |> Jsont.Object.mem "separator" separator_jsont ~enc:(fun t -> t.separator)
556556- |> Jsont.Object.skip_unknown
557557- |> Jsont.Object.finish
615615+ |> Jsont.Object.mem "separator" separator_jsont ~enc:(fun t ->
616616+ t.separator)
617617+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
558618 end
559619560620 type t = [ `Default of Default.t | `Other of Other_ext.t ]
561621 end
562622563623 let chunk_key_encoding_jsont : Chunk_key_encoding.t Jsont.t =
564564- let default_codec = Jsont.map ~kind:"default_encoding"
565565- ~dec:(fun d -> `Default d)
566566- ~enc:(function `Default d -> d | _ -> assert false)
567567- Chunk_key_encoding.Default.jsont
624624+ let default_codec =
625625+ Jsont.map ~kind:"default_encoding"
626626+ ~dec:(fun d -> `Default d)
627627+ ~enc:(function `Default d -> d | _ -> assert false)
628628+ Chunk_key_encoding.Default.jsont
568629 in
569630 Jsont.map ~kind:"V3.Chunk_key_encoding"
570570- ~dec:(fun json -> name_dispatch ~kind:"chunk_key_encoding" ["default", default_codec] json)
631631+ ~dec:(fun json ->
632632+ name_dispatch ~kind:"chunk_key_encoding"
633633+ [ ("default", default_codec) ]
634634+ json)
571635 ~enc:(function
572636 | `Default d ->
573573- encode_named "default" (Some (encode_config Chunk_key_encoding.Default.jsont d))
637637+ encode_named "default"
638638+ (Some (encode_config Chunk_key_encoding.Default.jsont d))
574639 | `Other o -> encode_other_ext o)
575640 Jsont.json
576641···601666 let array_meta_jsont : Array_meta.t Jsont.t =
602667 Jsont.Object.map ~kind:"V3.Array_meta"
603668 (fun _zarr_format _node_type sh dt cg cke cs fv dn st _attrs unk ->
604604- Array_meta.{
605605- shape = sh; data_type = dt; chunk_grid = cg; chunk_key_encoding = cke;
606606- codecs = cs; fill_value = fv; dimension_names = dn; storage_transformers = st;
607607- unknown = unk;
608608- })
669669+ Array_meta.
670670+ {
671671+ shape = sh;
672672+ data_type = dt;
673673+ chunk_grid = cg;
674674+ chunk_key_encoding = cke;
675675+ codecs = cs;
676676+ fill_value = fv;
677677+ dimension_names = dn;
678678+ storage_transformers = st;
679679+ unknown = unk;
680680+ })
609681 |> Jsont.Object.mem "zarr_format" Jsont.int ~enc:(fun _ -> 3)
610682 |> Jsont.Object.mem "node_type" Jsont.string ~enc:(fun _ -> "array")
611683 |> Jsont.Object.mem "shape" (Jsont.list Jsont.int)
···623695 |> Jsont.Object.opt_mem "dimension_names"
624696 (Jsont.list (Jsont.option Jsont.string))
625697 ~enc:(fun (t : Array_meta.t) -> t.dimension_names)
626626- |> Jsont.Object.opt_mem "storage_transformers"
627627- (Jsont.list Other_ext.jsont)
698698+ |> Jsont.Object.opt_mem "storage_transformers" (Jsont.list Other_ext.jsont)
628699 ~enc:(fun (t : Array_meta.t) -> t.storage_transformers)
629629- |> Jsont.Object.opt_mem "attributes" Jsont.json
630630- ~enc:(fun _ -> None)
631631- |> Jsont.Object.keep_unknown Jsont.json_mems
632632- ~enc:(fun (t : Array_meta.t) -> t.unknown)
700700+ |> Jsont.Object.opt_mem "attributes" Jsont.json ~enc:(fun _ -> None)
701701+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (t : Array_meta.t) ->
702702+ t.unknown)
633703 |> Jsont.Object.finish
634704end
635705···658728 |> Jsont.Object.mem "cname" Jsont.string ~enc:(fun t -> t.cname)
659729 |> Jsont.Object.mem "clevel" Jsont.int ~enc:(fun t -> t.clevel)
660730 |> Jsont.Object.mem "shuffle" Jsont.int ~enc:(fun t -> t.shuffle)
661661- |> Jsont.Object.opt_mem "blocksize" Jsont.int ~enc:(fun t -> t.blocksize)
731731+ |> Jsont.Object.opt_mem "blocksize" Jsont.int ~enc:(fun t ->
732732+ t.blocksize)
662733 |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
663734 |> Jsont.Object.finish
664735 end
665736666737 module Zlib = struct
667667- type t = {
668668- level : int;
669669- unknown : Jsont.json;
670670- }
738738+ type t = { level : int; unknown : Jsont.json }
671739672740 let level t = t.level
673741 let unknown t = t.unknown
674742675743 let jsont =
676676- Jsont.Object.map ~kind:"Zlib"
677677- (fun _id level unknown -> { level; unknown })
744744+ Jsont.Object.map ~kind:"Zlib" (fun _id level unknown ->
745745+ { level; unknown })
678746 |> Jsont.Object.mem "id" Jsont.string ~enc:(fun _ -> "zlib")
679747 |> Jsont.Object.mem "level" Jsont.int ~enc:(fun t -> t.level)
680748 |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
···682750 end
683751 end
684752685685- type compressor = [
686686- | `Blosc of Compressor.Blosc.t
753753+ type compressor =
754754+ [ `Blosc of Compressor.Blosc.t
687755 | `Zlib of Compressor.Zlib.t
688688- | `Other of Other_codec.t
689689- ]
756756+ | `Other of Other_codec.t ]
690757691758 let find_id mems =
692692- List.find_map (fun ((name, _), value) ->
693693- if name = "id" then
694694- match value with
695695- | Jsont.String (s, _) -> Some s
696696- | _ -> None
697697- else None) mems
759759+ List.find_map
760760+ (fun ((name, _), value) ->
761761+ if name = "id" then
762762+ match value with Jsont.String (s, _) -> Some s | _ -> None
763763+ else None)
764764+ mems
698765699766 let compressor_jsont : compressor Jsont.t =
700767 Jsont.map ~kind:"V2.Compressor"
701768 ~dec:(fun json ->
702769 match json with
703703- | Jsont.Object (mems, _meta) ->
704704- let id = find_id mems in
705705- (match id with
706706- | Some "blosc" -> `Blosc (jdec Compressor.Blosc.jsont json)
707707- | Some "zlib" -> `Zlib (jdec Compressor.Zlib.jsont json)
708708- | _ -> `Other (jdec Other_codec.jsont json))
770770+ | Jsont.Object (mems, _meta) -> (
771771+ let id = find_id mems in
772772+ match id with
773773+ | Some "blosc" -> `Blosc (jdec Compressor.Blosc.jsont json)
774774+ | Some "zlib" -> `Zlib (jdec Compressor.Zlib.jsont json)
775775+ | _ -> `Other (jdec Other_codec.jsont json))
709776 | _ -> Jsont.Error.msgf Jsont.Meta.none "V2.Compressor: expected object")
710777 ~enc:(function
711778 | `Blosc b -> jenc Compressor.Blosc.jsont b
···715782716783 module Filter = struct
717784 module Delta = struct
718718- type t = {
719719- dtype : string;
720720- astype : string option;
721721- unknown : Jsont.json;
722722- }
785785+ type t = { dtype : string; astype : string option; unknown : Jsont.json }
723786724787 let dtype t = t.dtype
725788 let astype t = t.astype
726789 let unknown t = t.unknown
727790728791 let jsont =
729729- Jsont.Object.map ~kind:"Delta"
730730- (fun _id dtype astype unknown -> { dtype; astype; unknown })
792792+ Jsont.Object.map ~kind:"Delta" (fun _id dtype astype unknown ->
793793+ { dtype; astype; unknown })
731794 |> Jsont.Object.mem "id" Jsont.string ~enc:(fun _ -> "delta")
732795 |> Jsont.Object.mem "dtype" Jsont.string ~enc:(fun t -> t.dtype)
733796 |> Jsont.Object.opt_mem "astype" Jsont.string ~enc:(fun t -> t.astype)
···736799 end
737800 end
738801739739- type filter = [
740740- | `Delta of Filter.Delta.t
741741- | `Other of Other_codec.t
742742- ]
802802+ type filter = [ `Delta of Filter.Delta.t | `Other of Other_codec.t ]
743803744804 let filter_jsont : filter Jsont.t =
745805 Jsont.map ~kind:"V2.Filter"
746806 ~dec:(fun json ->
747807 match json with
748748- | Jsont.Object (mems, _meta) ->
749749- let id = find_id mems in
750750- (match id with
751751- | Some "delta" -> `Delta (jdec Filter.Delta.jsont json)
752752- | _ -> `Other (jdec Other_codec.jsont json))
808808+ | Jsont.Object (mems, _meta) -> (
809809+ let id = find_id mems in
810810+ match id with
811811+ | Some "delta" -> `Delta (jdec Filter.Delta.jsont json)
812812+ | _ -> `Other (jdec Other_codec.jsont json))
753813 | _ -> Jsont.Error.msgf Jsont.Meta.none "V2.Filter: expected object")
754814 ~enc:(function
755815 | `Delta d -> jenc Filter.Delta.jsont d
···768828 dimension_separator : [ `Dot | `Slash ] option;
769829 unknown : Jsont.json;
770830 }
831831+771832 let shape t = t.shape
772833 let chunks t = t.chunks
773834 let dtype t = t.dtype
···780841 end
781842782843 let array_meta_jsont =
783783- let order_jsont = Jsont.enum ~kind:"order" ["C", `C; "F", `F] in
784784- let dim_sep_jsont = Jsont.enum ~kind:"dimension_separator" [".", `Dot; "/", `Slash] in
844844+ let order_jsont = Jsont.enum ~kind:"order" [ ("C", `C); ("F", `F) ] in
845845+ let dim_sep_jsont =
846846+ Jsont.enum ~kind:"dimension_separator" [ (".", `Dot); ("/", `Slash) ]
847847+ in
785848 Jsont.Object.map ~kind:"V2.Array_meta"
786849 (fun _zarr_format s c d comp fv ord filt dim_sep unk ->
787787- Array_meta.{ shape = s; chunks = c; dtype = d; compressor = comp; fill_value = fv; order = ord; filters = filt; dimension_separator = dim_sep; unknown = unk })
850850+ Array_meta.
851851+ {
852852+ shape = s;
853853+ chunks = c;
854854+ dtype = d;
855855+ compressor = comp;
856856+ fill_value = fv;
857857+ order = ord;
858858+ filters = filt;
859859+ dimension_separator = dim_sep;
860860+ unknown = unk;
861861+ })
788862 |> Jsont.Object.mem "zarr_format" Jsont.int ~enc:(fun _ -> 2)
789789- |> Jsont.Object.mem "shape" (Jsont.list Jsont.int) ~enc:(fun (t : Array_meta.t) -> t.shape)
790790- |> Jsont.Object.mem "chunks" (Jsont.list Jsont.int) ~enc:(fun (t : Array_meta.t) -> t.chunks)
791791- |> Jsont.Object.mem "dtype" dtype_jsont ~enc:(fun (t : Array_meta.t) -> t.dtype)
792792- |> Jsont.Object.mem "compressor" (Jsont.option compressor_jsont) ~enc:(fun (t : Array_meta.t) -> t.compressor)
793793- |> Jsont.Object.mem "fill_value" fill_value_jsont ~enc:(fun (t : Array_meta.t) -> t.fill_value)
794794- |> Jsont.Object.mem "order" order_jsont ~enc:(fun (t : Array_meta.t) -> t.order)
795795- |> Jsont.Object.mem "filters" (Jsont.option (Jsont.list filter_jsont)) ~enc:(fun (t : Array_meta.t) -> t.filters)
796796- |> Jsont.Object.opt_mem "dimension_separator" dim_sep_jsont ~enc:(fun (t : Array_meta.t) -> t.dimension_separator)
797797- |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (t : Array_meta.t) -> t.unknown)
863863+ |> Jsont.Object.mem "shape" (Jsont.list Jsont.int)
864864+ ~enc:(fun (t : Array_meta.t) -> t.shape)
865865+ |> Jsont.Object.mem "chunks" (Jsont.list Jsont.int)
866866+ ~enc:(fun (t : Array_meta.t) -> t.chunks)
867867+ |> Jsont.Object.mem "dtype" dtype_jsont ~enc:(fun (t : Array_meta.t) ->
868868+ t.dtype)
869869+ |> Jsont.Object.mem "compressor" (Jsont.option compressor_jsont)
870870+ ~enc:(fun (t : Array_meta.t) -> t.compressor)
871871+ |> Jsont.Object.mem "fill_value" fill_value_jsont
872872+ ~enc:(fun (t : Array_meta.t) -> t.fill_value)
873873+ |> Jsont.Object.mem "order" order_jsont ~enc:(fun (t : Array_meta.t) ->
874874+ t.order)
875875+ |> Jsont.Object.mem "filters"
876876+ (Jsont.option (Jsont.list filter_jsont))
877877+ ~enc:(fun (t : Array_meta.t) -> t.filters)
878878+ |> Jsont.Object.opt_mem "dimension_separator" dim_sep_jsont
879879+ ~enc:(fun (t : Array_meta.t) -> t.dimension_separator)
880880+ |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (t : Array_meta.t) ->
881881+ t.unknown)
798882 |> Jsont.Object.finish
799883end
800884···820904 { uuid; name; schema_url; spec_url; description })
821905 |> Jsont.Object.mem "uuid" Jsont.string ~enc:(fun t -> t.uuid)
822906 |> Jsont.Object.mem "name" Jsont.string ~enc:(fun t -> t.name)
823823- |> Jsont.Object.opt_mem "schema_url" Jsont.string ~enc:(fun t -> t.schema_url)
907907+ |> Jsont.Object.opt_mem "schema_url" Jsont.string ~enc:(fun t ->
908908+ t.schema_url)
824909 |> Jsont.Object.opt_mem "spec_url" Jsont.string ~enc:(fun t -> t.spec_url)
825825- |> Jsont.Object.opt_mem "description" Jsont.string ~enc:(fun t -> t.description)
826826- |> Jsont.Object.skip_unknown
827827- |> Jsont.Object.finish
910910+ |> Jsont.Object.opt_mem "description" Jsont.string ~enc:(fun t ->
911911+ t.description)
912912+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
828913 end
829914830915 module Proj = struct
···838923 let wkt2 t = t.wkt2
839924 let projjson t = t.projjson
840925841841- let meta = { Meta.
842842- uuid = "f17cb550-5864-4468-aeb7-f3180cfb622f";
843843- name = "proj:";
844844- schema_url = Some "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v1/schema.json";
845845- spec_url = Some "https://github.com/zarr-experimental/geo-proj/blob/v1/README.md";
846846- description = Some "Coordinate reference system information for geospatial data";
847847- }
926926+ let meta =
927927+ {
928928+ Meta.uuid = "f17cb550-5864-4468-aeb7-f3180cfb622f";
929929+ name = "proj:";
930930+ schema_url =
931931+ Some
932932+ "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v1/schema.json";
933933+ spec_url =
934934+ Some "https://github.com/zarr-experimental/geo-proj/blob/v1/README.md";
935935+ description =
936936+ Some "Coordinate reference system information for geospatial data";
937937+ }
848938849939 let jsont =
850850- Jsont.Object.map ~kind:"Conv.Proj"
851851- (fun code wkt2 projjson -> { code; wkt2; projjson })
940940+ Jsont.Object.map ~kind:"Conv.Proj" (fun code wkt2 projjson ->
941941+ { code; wkt2; projjson })
852942 |> Jsont.Object.opt_mem "proj:code" Jsont.string ~enc:(fun t -> t.code)
853943 |> Jsont.Object.opt_mem "proj:wkt2" Jsont.string ~enc:(fun t -> t.wkt2)
854854- |> Jsont.Object.opt_mem "proj:projjson" Jsont.json ~enc:(fun t -> t.projjson)
855855- |> Jsont.Object.skip_unknown
856856- |> Jsont.Object.finish
944944+ |> Jsont.Object.opt_mem "proj:projjson" Jsont.json ~enc:(fun t ->
945945+ t.projjson)
946946+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
857947 end
858948859949 module Spatial = struct
···873963 let shape t = t.shape
874964 let registration t = t.registration
875965876876- let meta = { Meta.
877877- uuid = "689b58e2-cf7b-45e0-9fff-9cfc0883d6b4";
878878- name = "spatial:";
879879- schema_url = Some "https://raw.githubusercontent.com/zarr-conventions/spatial/refs/tags/v1/schema.json";
880880- spec_url = Some "https://github.com/zarr-conventions/spatial/blob/v1/README.md";
881881- description = Some "Spatial coordinate information";
882882- }
966966+ let meta =
967967+ {
968968+ Meta.uuid = "689b58e2-cf7b-45e0-9fff-9cfc0883d6b4";
969969+ name = "spatial:";
970970+ schema_url =
971971+ Some
972972+ "https://raw.githubusercontent.com/zarr-conventions/spatial/refs/tags/v1/schema.json";
973973+ spec_url =
974974+ Some "https://github.com/zarr-conventions/spatial/blob/v1/README.md";
975975+ description = Some "Spatial coordinate information";
976976+ }
883977884978 let jsont =
885885- let registration_jsont = Jsont.enum ~kind:"registration" ["pixel", `Pixel; "node", `Node] in
979979+ let registration_jsont =
980980+ Jsont.enum ~kind:"registration" [ ("pixel", `Pixel); ("node", `Node) ]
981981+ in
886982 Jsont.Object.map ~kind:"Conv.Spatial"
887983 (fun dimensions bbox transform_type transform shape registration ->
888984 { dimensions; bbox; transform_type; transform; shape; registration })
889889- |> Jsont.Object.mem "spatial:dimensions" (Jsont.list Jsont.string) ~enc:(fun t -> t.dimensions)
890890- |> Jsont.Object.opt_mem "spatial:bbox" (Jsont.list Jsont.number) ~enc:(fun t -> t.bbox)
891891- |> Jsont.Object.opt_mem "spatial:transform_type" Jsont.string ~enc:(fun t -> t.transform_type)
892892- |> Jsont.Object.opt_mem "spatial:transform" (Jsont.list Jsont.number) ~enc:(fun t -> t.transform)
893893- |> Jsont.Object.opt_mem "spatial:shape" (Jsont.list Jsont.int) ~enc:(fun t -> t.shape)
894894- |> Jsont.Object.opt_mem "spatial:registration" registration_jsont ~enc:(fun t -> t.registration)
895895- |> Jsont.Object.skip_unknown
896896- |> Jsont.Object.finish
985985+ |> Jsont.Object.mem "spatial:dimensions" (Jsont.list Jsont.string)
986986+ ~enc:(fun t -> t.dimensions)
987987+ |> Jsont.Object.opt_mem "spatial:bbox" (Jsont.list Jsont.number)
988988+ ~enc:(fun t -> t.bbox)
989989+ |> Jsont.Object.opt_mem "spatial:transform_type" Jsont.string
990990+ ~enc:(fun t -> t.transform_type)
991991+ |> Jsont.Object.opt_mem "spatial:transform" (Jsont.list Jsont.number)
992992+ ~enc:(fun t -> t.transform)
993993+ |> Jsont.Object.opt_mem "spatial:shape" (Jsont.list Jsont.int)
994994+ ~enc:(fun t -> t.shape)
995995+ |> Jsont.Object.opt_mem "spatial:registration" registration_jsont
996996+ ~enc:(fun t -> t.registration)
997997+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
897998 end
8989998991000 module Geoemb = struct
···9051006 grid_id : string option;
9061007 grid_definition : string option;
9071008 }
10091009+9081010 let layout_type t = t.layout_type
9091011 let chip_size t = t.chip_size
9101012 let stride t = t.stride
9111013 let grid_id t = t.grid_id
9121014 let grid_definition t = t.grid_definition
9131015914914- let layout_type_jsont = Jsont.enum ~kind:"layout_type"
915915- ["regular_grid", `Regular_grid; "irregular", `Irregular]
10161016+ let layout_type_jsont =
10171017+ Jsont.enum ~kind:"layout_type"
10181018+ [ ("regular_grid", `Regular_grid); ("irregular", `Irregular) ]
91610199171020 let int_pair =
9181021 Jsont.t2 ~kind:"int_pair"
···9211024 Jsont.int
92210259231026 let jsont =
924924- Jsont.Object.map ~kind:"Chip_layout"
925925- (fun lt cs st gi gd -> { layout_type = lt; chip_size = cs;
926926- stride = st; grid_id = gi;
927927- grid_definition = gd })
928928- |> Jsont.Object.mem "layout_type" layout_type_jsont
929929- ~enc:(fun t -> t.layout_type)
10271027+ Jsont.Object.map ~kind:"Chip_layout" (fun lt cs st gi gd ->
10281028+ {
10291029+ layout_type = lt;
10301030+ chip_size = cs;
10311031+ stride = st;
10321032+ grid_id = gi;
10331033+ grid_definition = gd;
10341034+ })
10351035+ |> Jsont.Object.mem "layout_type" layout_type_jsont ~enc:(fun t ->
10361036+ t.layout_type)
9301037 |> Jsont.Object.mem "chip_size" int_pair ~enc:(fun t -> t.chip_size)
9311038 |> Jsont.Object.opt_mem "stride" int_pair ~enc:(fun t -> t.stride)
9321039 |> Jsont.Object.opt_mem "grid_id" Jsont.string ~enc:(fun t -> t.grid_id)
933933- |> Jsont.Object.opt_mem "grid_definition" Jsont.string
934934- ~enc:(fun t -> t.grid_definition)
935935- |> Jsont.Object.skip_unknown
936936- |> Jsont.Object.finish
10401040+ |> Jsont.Object.opt_mem "grid_definition" Jsont.string ~enc:(fun t ->
10411041+ t.grid_definition)
10421042+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
9371043 end
93810449391045 module Scale = struct
9401046 module Scalar = struct
9411047 type t = { scale : float; offset : float }
10481048+9421049 let scale t = t.scale
9431050 let offset t = t.offset
10511051+9441052 let jsont =
945945- Jsont.Object.map ~kind:"Scale.Scalar"
946946- (fun scale offset ->
10531053+ Jsont.Object.map ~kind:"Scale.Scalar" (fun scale offset ->
9471054 { scale; offset = Option.value ~default:0.0 offset })
9481055 |> Jsont.Object.mem "scale" Jsont.number ~enc:(fun t -> t.scale)
949949- |> Jsont.Object.opt_mem "offset" Jsont.number
950950- ~enc:(fun t ->
951951- if t.offset = 0.0 then None else Some t.offset)
952952- |> Jsont.Object.skip_unknown
953953- |> Jsont.Object.finish
10561056+ |> Jsont.Object.opt_mem "offset" Jsont.number ~enc:(fun t ->
10571057+ if t.offset = 0.0 then None else Some t.offset)
10581058+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
9541059 end
10601060+9551061 module Array_ = struct
9561062 type t = { array_name : string; nodata : string option }
10631063+9571064 let array_name t = t.array_name
9581065 let nodata t = t.nodata
10661066+9591067 let nodata_jsont =
960960- let from_string = Jsont.map ~kind:"nodata"
961961- ~dec:Fun.id ~enc:Fun.id Jsont.string in
962962- let from_number = Jsont.map ~kind:"nodata"
963963- ~dec:(fun f -> Printf.sprintf "%g" f)
964964- ~enc:(fun _ -> 0.0)
965965- Jsont.number in
966966- Jsont.any ~kind:"nodata"
967967- ~dec_string:from_string ~dec_number:from_number
968968- ~enc:(fun _ -> from_string) ()
10681068+ let from_string =
10691069+ Jsont.map ~kind:"nodata" ~dec:Fun.id ~enc:Fun.id Jsont.string
10701070+ in
10711071+ let from_number =
10721072+ Jsont.map ~kind:"nodata"
10731073+ ~dec:(fun f -> Printf.sprintf "%g" f)
10741074+ ~enc:(fun _ -> 0.0)
10751075+ Jsont.number
10761076+ in
10771077+ Jsont.any ~kind:"nodata" ~dec_string:from_string
10781078+ ~dec_number:from_number
10791079+ ~enc:(fun _ -> from_string)
10801080+ ()
10811081+9691082 let jsont =
970970- Jsont.Object.map ~kind:"Scale.Array"
971971- (fun array_name nodata -> { array_name; nodata })
972972- |> Jsont.Object.mem "array_name" Jsont.string
973973- ~enc:(fun t -> t.array_name)
974974- |> Jsont.Object.opt_mem "nodata" nodata_jsont
975975- ~enc:(fun t -> t.nodata)
976976- |> Jsont.Object.skip_unknown
977977- |> Jsont.Object.finish
10831083+ Jsont.Object.map ~kind:"Scale.Array" (fun array_name nodata ->
10841084+ { array_name; nodata })
10851085+ |> Jsont.Object.mem "array_name" Jsont.string ~enc:(fun t ->
10861086+ t.array_name)
10871087+ |> Jsont.Object.opt_mem "nodata" nodata_jsont ~enc:(fun t -> t.nodata)
10881088+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
9781089 end
10901090+9791091 type t = [ `Scalar of Scalar.t | `Array of Array_.t ]
98010929811093 let jsont =
982982- let scalar = Jsont.Object.Case.map ~dec:(fun s -> `Scalar s)
983983- "scalar" Scalar.jsont in
984984- let array_ = Jsont.Object.Case.map ~dec:(fun a -> `Array a)
985985- "array" Array_.jsont in
10941094+ let scalar =
10951095+ Jsont.Object.Case.map ~dec:(fun s -> `Scalar s) "scalar" Scalar.jsont
10961096+ in
10971097+ let array_ =
10981098+ Jsont.Object.Case.map ~dec:(fun a -> `Array a) "array" Array_.jsont
10991099+ in
9861100 let enc_case = function
9871101 | `Scalar s -> Jsont.Object.Case.value scalar s
9881102 | `Array a -> Jsont.Object.Case.value array_ a
9891103 in
9901104 Jsont.Object.map ~kind:"Scale" Fun.id
991991- |> Jsont.Object.case_mem "type" Jsont.string
992992- ~enc:Fun.id ~enc_case
11051105+ |> Jsont.Object.case_mem "type" Jsont.string ~enc:Fun.id ~enc_case
9931106 ~tag_to_string:Fun.id ~tag_compare:String.compare
994994- Jsont.Object.Case.[make scalar; make array_]
11071107+ Jsont.Object.Case.[ make scalar; make array_ ]
9951108 |> Jsont.Object.finish
9961109 end
9971110···10031116 scale : Scale.t option;
10041117 link : string option;
10051118 }
11191119+10061120 let meth t = t.meth
10071121 let original_dtype t = t.original_dtype
10081122 let quantized_dtype t = t.quantized_dtype
10091123 let scale t = t.scale
10101124 let link t = t.link
11251125+10111126 let jsont =
10121012- Jsont.Object.map ~kind:"Quantization"
10131013- (fun m od qd sc lk ->
10141014- { meth = m; original_dtype = od; quantized_dtype = qd;
10151015- scale = sc; link = lk })
11271127+ Jsont.Object.map ~kind:"Quantization" (fun m od qd sc lk ->
11281128+ {
11291129+ meth = m;
11301130+ original_dtype = od;
11311131+ quantized_dtype = qd;
11321132+ scale = sc;
11331133+ link = lk;
11341134+ })
10161135 |> Jsont.Object.mem "method" Jsont.string ~enc:(fun t -> t.meth)
10171017- |> Jsont.Object.mem "original_dtype" Jsont.string
10181018- ~enc:(fun t -> t.original_dtype)
10191019- |> Jsont.Object.opt_mem "quantized_dtype" Jsont.string
10201020- ~enc:(fun t -> t.quantized_dtype)
11361136+ |> Jsont.Object.mem "original_dtype" Jsont.string ~enc:(fun t ->
11371137+ t.original_dtype)
11381138+ |> Jsont.Object.opt_mem "quantized_dtype" Jsont.string ~enc:(fun t ->
11391139+ t.quantized_dtype)
10211140 |> Jsont.Object.opt_mem "scale" Scale.jsont ~enc:(fun t -> t.scale)
10221141 |> Jsont.Object.opt_mem "link" Jsont.string ~enc:(fun t -> t.link)
10231023- |> Jsont.Object.skip_unknown
10241024- |> Jsont.Object.finish
11421142+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
10251143 end
1026114410271145 type t = {
···10371155 build_version : string option;
10381156 benchmark : string list option;
10391157 }
11581158+10401159 let type_ t = t.type_
10411160 let dimensions t = t.dimensions
10421161 let model t = t.model
···10491168 let build_version t = t.build_version
10501169 let benchmark t = t.benchmark
1051117010521052- let meta = { Meta.
10531053- uuid = "61c12cc5-0e28-4056-999a-480cf3fb7e4c";
10541054- name = "geoemb:";
10551055- schema_url = Some "https://raw.githubusercontent.com/geo-embeddings/embeddings-zarr-convention/refs/tags/v1/schema.json";
10561056- spec_url = Some "https://github.com/geo-embeddings/embeddings-zarr-convention/blob/v1/README.md";
10571057- description = Some "Geoembeddings convention for geospatial embedding arrays with model provenance";
10581058- }
11711171+ let meta =
11721172+ {
11731173+ Meta.uuid = "61c12cc5-0e28-4056-999a-480cf3fb7e4c";
11741174+ name = "geoemb:";
11751175+ schema_url =
11761176+ Some
11771177+ "https://raw.githubusercontent.com/geo-embeddings/embeddings-zarr-convention/refs/tags/v1/schema.json";
11781178+ spec_url =
11791179+ Some
11801180+ "https://github.com/geo-embeddings/embeddings-zarr-convention/blob/v1/README.md";
11811181+ description =
11821182+ Some
11831183+ "Geoembeddings convention for geospatial embedding arrays with \
11841184+ model provenance";
11851185+ }
1059118610601060- let type_jsont = Jsont.enum ~kind:"geoemb_type" ["pixel", `Pixel; "chip", `Chip]
11871187+ let type_jsont =
11881188+ Jsont.enum ~kind:"geoemb_type" [ ("pixel", `Pixel); ("chip", `Chip) ]
1061118910621190 let jsont =
10631191 Jsont.Object.map ~kind:"Geoemb"
10641192 (fun ty dim mdl src dt gsd cl qu sl bv bm ->
10651065- { type_ = ty; dimensions = dim; model = mdl; source_data = src;
10661066- data_type = dt; gsd; chip_layout = cl; quantization = qu;
10671067- spatial_layout = sl; build_version = bv; benchmark = bm })
11931193+ {
11941194+ type_ = ty;
11951195+ dimensions = dim;
11961196+ model = mdl;
11971197+ source_data = src;
11981198+ data_type = dt;
11991199+ gsd;
12001200+ chip_layout = cl;
12011201+ quantization = qu;
12021202+ spatial_layout = sl;
12031203+ build_version = bv;
12041204+ benchmark = bm;
12051205+ })
10681206 |> Jsont.Object.mem "geoemb:type" type_jsont ~enc:(fun t -> t.type_)
10691069- |> Jsont.Object.mem "geoemb:dimensions" Jsont.int
10701070- ~enc:(fun t -> t.dimensions)
12071207+ |> Jsont.Object.mem "geoemb:dimensions" Jsont.int ~enc:(fun t ->
12081208+ t.dimensions)
10711209 |> Jsont.Object.mem "geoemb:model" Jsont.string ~enc:(fun t -> t.model)
10721210 |> Jsont.Object.mem "geoemb:source_data" (Jsont.list Jsont.string)
10731211 ~enc:(fun t -> t.source_data)
10741074- |> Jsont.Object.mem "geoemb:data_type" Jsont.string
10751075- ~enc:(fun t -> t.data_type)
12121212+ |> Jsont.Object.mem "geoemb:data_type" Jsont.string ~enc:(fun t ->
12131213+ t.data_type)
10761214 |> Jsont.Object.opt_mem "geoemb:gsd" Jsont.number ~enc:(fun t -> t.gsd)
10771215 |> Jsont.Object.opt_mem "geoemb:chip_layout" Chip_layout.jsont
10781216 ~enc:(fun t -> t.chip_layout)
···10801218 ~enc:(fun t -> t.quantization)
10811219 |> Jsont.Object.opt_mem "geoemb:spatial_layout" Jsont.string
10821220 ~enc:(fun t -> t.spatial_layout)
10831083- |> Jsont.Object.opt_mem "geoemb:build_version" Jsont.string
10841084- ~enc:(fun t -> t.build_version)
12211221+ |> Jsont.Object.opt_mem "geoemb:build_version" Jsont.string ~enc:(fun t ->
12221222+ t.build_version)
10851223 |> Jsont.Object.opt_mem "geoemb:benchmark" (Jsont.list Jsont.string)
10861224 ~enc:(fun t -> t.benchmark)
10871087- |> Jsont.Object.skip_unknown
10881088- |> Jsont.Object.finish
12251225+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
10891226 end
1090122710911228 module Multiscales = struct
···11031240 let jsont =
11041241 Jsont.Object.map ~kind:"Conv.Multiscales.Transform"
11051242 (fun scale translation unknown -> { scale; translation; unknown })
11061106- |> Jsont.Object.opt_mem "scale" (Jsont.list Jsont.number) ~enc:(fun t -> t.scale)
11071107- |> Jsont.Object.opt_mem "translation" (Jsont.list Jsont.number) ~enc:(fun t -> t.translation)
12431243+ |> Jsont.Object.opt_mem "scale" (Jsont.list Jsont.number) ~enc:(fun t ->
12441244+ t.scale)
12451245+ |> Jsont.Object.opt_mem "translation" (Jsont.list Jsont.number)
12461246+ ~enc:(fun t -> t.translation)
11081247 |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
11091248 |> Jsont.Object.finish
11101249 end
···11291268 (fun asset derived_from transform resampling_method unknown ->
11301269 { asset; derived_from; transform; resampling_method; unknown })
11311270 |> Jsont.Object.mem "asset" Jsont.string ~enc:(fun t -> t.asset)
11321132- |> Jsont.Object.opt_mem "derived_from" Jsont.string ~enc:(fun t -> t.derived_from)
11331133- |> Jsont.Object.opt_mem "transform" Transform.jsont ~enc:(fun t -> t.transform)
11341134- |> Jsont.Object.opt_mem "resampling_method" Jsont.string ~enc:(fun t -> t.resampling_method)
12711271+ |> Jsont.Object.opt_mem "derived_from" Jsont.string ~enc:(fun t ->
12721272+ t.derived_from)
12731273+ |> Jsont.Object.opt_mem "transform" Transform.jsont ~enc:(fun t ->
12741274+ t.transform)
12751275+ |> Jsont.Object.opt_mem "resampling_method" Jsont.string ~enc:(fun t ->
12761276+ t.resampling_method)
11351277 |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun t -> t.unknown)
11361278 |> Jsont.Object.finish
11371279 end
1138128011391139- type t = {
11401140- layout : Layout_item.t list;
11411141- resampling_method : string option;
11421142- }
12811281+ type t = { layout : Layout_item.t list; resampling_method : string option }
1143128211441283 let layout t = t.layout
11451284 let resampling_method t = t.resampling_method
1146128511471147- let meta = { Meta.
11481148- uuid = "d35379db-88df-4056-af3a-620245f8e347";
11491149- name = "multiscales";
11501150- schema_url = Some "https://raw.githubusercontent.com/zarr-conventions/multiscales/refs/tags/v1/schema.json";
11511151- spec_url = Some "https://github.com/zarr-conventions/multiscales/blob/v1/README.md";
11521152- description = Some "Multiscale layout of zarr datasets";
11531153- }
12861286+ let meta =
12871287+ {
12881288+ Meta.uuid = "d35379db-88df-4056-af3a-620245f8e347";
12891289+ name = "multiscales";
12901290+ schema_url =
12911291+ Some
12921292+ "https://raw.githubusercontent.com/zarr-conventions/multiscales/refs/tags/v1/schema.json";
12931293+ spec_url =
12941294+ Some
12951295+ "https://github.com/zarr-conventions/multiscales/blob/v1/README.md";
12961296+ description = Some "Multiscale layout of zarr datasets";
12971297+ }
1154129811551299 let jsont =
11561156- Jsont.Object.map ~kind:"Conv.Multiscales"
11571157- (fun layout resampling_method -> { layout; resampling_method })
11581158- |> Jsont.Object.mem "layout" (Jsont.list Layout_item.jsont) ~enc:(fun t -> t.layout)
11591159- |> Jsont.Object.opt_mem "resampling_method" Jsont.string ~enc:(fun t -> t.resampling_method)
11601160- |> Jsont.Object.skip_unknown
11611161- |> Jsont.Object.finish
13001300+ Jsont.Object.map ~kind:"Conv.Multiscales" (fun layout resampling_method ->
13011301+ { layout; resampling_method })
13021302+ |> Jsont.Object.mem "layout" (Jsont.list Layout_item.jsont) ~enc:(fun t ->
13031303+ t.layout)
13041304+ |> Jsont.Object.opt_mem "resampling_method" Jsont.string ~enc:(fun t ->
13051305+ t.resampling_method)
13061306+ |> Jsont.Object.skip_unknown |> Jsont.Object.finish
11621307 end
11631308end
11641309···11711316 geoemb : Conv.Geoemb.t option;
11721317 unknown : Jsont.json;
11731318 }
13191319+11741320 let conventions t = t.conventions
11751321 let proj t = t.proj
11761322 let spatial t = t.spatial
11771323 let multiscales t = t.multiscales
11781324 let geoemb t = t.geoemb
11791325 let unknown t = t.unknown
11801180- let empty = {
11811181- conventions = []; proj = None; spatial = None; multiscales = None;
11821182- geoemb = None; unknown = Jsont.Json.object' [];
11831183- }
13261326+13271327+ let empty =
13281328+ {
13291329+ conventions = [];
13301330+ proj = None;
13311331+ spatial = None;
13321332+ multiscales = None;
13331333+ geoemb = None;
13341334+ unknown = Jsont.Json.object' [];
13351335+ }
11841336end
1185133711861338let emit_prefixed prefix conv_jsont value add =
11871339 match value with
11881340 | None -> ()
11891189- | Some v ->
11901190- match Jsont.Json.encode conv_jsont v with
11911191- | Ok (Jsont.Object (ms, _)) ->
11921192- List.iter (fun ((k, _), _ as m) ->
11931193- if String.length k > String.length prefix
11941194- && String.sub k 0 (String.length prefix) = prefix
11951195- then add m) ms
11961196- | _ -> ()
13411341+ | Some v -> (
13421342+ match Jsont.Json.encode conv_jsont v with
13431343+ | Ok (Jsont.Object (ms, _)) ->
13441344+ List.iter
13451345+ (fun (((k, _), _) as m) ->
13461346+ if
13471347+ String.length k > String.length prefix
13481348+ && String.sub k 0 (String.length prefix) = prefix
13491349+ then add m)
13501350+ ms
13511351+ | _ -> ())
1197135211981353let attrs_jsont : Attrs.t Jsont.t =
11991354 Jsont.map ~kind:"Attrs"
12001355 ~dec:(fun json ->
12011201- let mems = match json with
12021202- | Jsont.Object (mems, _) -> mems
12031203- | _ -> []
12041204- in
13561356+ let mems = match json with Jsont.Object (mems, _) -> mems | _ -> [] in
12051357 let find_mem name =
12061206- List.find_map (fun ((k, _), v) ->
12071207- if k = name then Some v else None) mems
13581358+ List.find_map
13591359+ (fun ((k, _), v) -> if k = name then Some v else None)
13601360+ mems
12081361 in
12091362 let is_known ((k, _), _) =
12101210- k = "zarr_conventions" || k = "multiscales" ||
12111211- (String.length k > 5 && String.sub k 0 5 = "proj:") ||
12121212- (String.length k > 8 && String.sub k 0 8 = "spatial:") ||
12131213- (String.length k > 7 && String.sub k 0 7 = "geoemb:")
13631363+ k = "zarr_conventions" || k = "multiscales"
13641364+ || (String.length k > 5 && String.sub k 0 5 = "proj:")
13651365+ || (String.length k > 8 && String.sub k 0 8 = "spatial:")
13661366+ || (String.length k > 7 && String.sub k 0 7 = "geoemb:")
12141367 in
12151368 (* zarr_conventions *)
12161216- let convs = match find_mem "zarr_conventions" with
12171217- | Some arr ->
12181218- (match Jsont.Json.decode (Jsont.list Conv.Meta.jsont) arr with
12191219- | Ok cs -> cs | Error _ -> [])
13691369+ let convs =
13701370+ match find_mem "zarr_conventions" with
13711371+ | Some arr -> (
13721372+ match Jsont.Json.decode (Jsont.list Conv.Meta.jsont) arr with
13731373+ | Ok cs -> cs
13741374+ | Error _ -> [])
12201375 | None -> []
12211376 in
12221377 (* proj: try decoding if any proj: key exists *)
12231223- let has_proj = List.exists (fun ((k, _), _) ->
12241224- String.length k > 5 && String.sub k 0 5 = "proj:") mems
13781378+ let has_proj =
13791379+ List.exists
13801380+ (fun ((k, _), _) -> String.length k > 5 && String.sub k 0 5 = "proj:")
13811381+ mems
12251382 in
12261383 let proj_val =
12271384 if has_proj then
12281385 match Jsont.Json.decode Conv.Proj.jsont json with
12291229- | Ok p when Conv.Proj.code p <> None || Conv.Proj.wkt2 p <> None || Conv.Proj.projjson p <> None -> Some p
13861386+ | Ok p
13871387+ when Conv.Proj.code p <> None
13881388+ || Conv.Proj.wkt2 p <> None
13891389+ || Conv.Proj.projjson p <> None ->
13901390+ Some p
12301391 | _ -> None
12311392 else None
12321393 in
12331394 (* spatial: need spatial:dimensions to be present (it's required) *)
12341234- let has_spatial = List.exists (fun ((k, _), _) -> k = "spatial:dimensions") mems in
13951395+ let has_spatial =
13961396+ List.exists (fun ((k, _), _) -> k = "spatial:dimensions") mems
13971397+ in
12351398 let spatial_val =
12361399 if has_spatial then
12371400 match Jsont.Json.decode Conv.Spatial.jsont json with
12381238- | Ok s -> Some s | Error _ -> None
14011401+ | Ok s -> Some s
14021402+ | Error _ -> None
12391403 else None
12401404 in
12411405 (* multiscales: it's a nested object at key "multiscales" *)
12421242- let multiscales_val = match find_mem "multiscales" with
12431243- | Some ms_json ->
12441244- (match Jsont.Json.decode Conv.Multiscales.jsont ms_json with
12451245- | Ok m -> Some m | Error _ -> None)
14061406+ let multiscales_val =
14071407+ match find_mem "multiscales" with
14081408+ | Some ms_json -> (
14091409+ match Jsont.Json.decode Conv.Multiscales.jsont ms_json with
14101410+ | Ok m -> Some m
14111411+ | Error _ -> None)
12461412 | None -> None
12471413 in
12481414 (* geoemb: prefixed keys *)
12491249- let has_geoemb = List.exists (fun ((k, _), _) ->
12501250- k = "geoemb:type") mems in
14151415+ let has_geoemb =
14161416+ List.exists (fun ((k, _), _) -> k = "geoemb:type") mems
14171417+ in
12511418 let geoemb_val =
12521419 if has_geoemb then
12531420 match Jsont.Json.decode Conv.Geoemb.jsont json with
12541254- | Ok g -> Some g | Error _ -> None
14211421+ | Ok g -> Some g
14221422+ | Error _ -> None
12551423 else None
12561424 in
12571425 (* unknown: everything that's not a known convention key *)
12581426 let unknown_mems = List.filter (fun m -> not (is_known m)) mems in
12591427 let unknown_val = Jsont.Json.object' unknown_mems in
12601260- { Attrs.
12611261- conventions = convs;
14281428+ {
14291429+ Attrs.conventions = convs;
12621430 proj = proj_val;
12631431 spatial = spatial_val;
12641432 multiscales = multiscales_val;
···12701438 let add m = mems := m :: !mems in
12711439 (* Auto-populate zarr_conventions *)
12721440 let conv_metas =
12731273- (match t.geoemb with Some _ -> [Conv.Geoemb.meta] | None -> []) @
12741274- (match t.proj with Some _ -> [Conv.Proj.meta] | None -> []) @
12751275- (match t.spatial with Some _ -> [Conv.Spatial.meta] | None -> []) @
12761276- (match t.multiscales with Some _ -> [Conv.Multiscales.meta] | None -> [])
14411441+ (match t.geoemb with Some _ -> [ Conv.Geoemb.meta ] | None -> [])
14421442+ @ (match t.proj with Some _ -> [ Conv.Proj.meta ] | None -> [])
14431443+ @ (match t.spatial with Some _ -> [ Conv.Spatial.meta ] | None -> [])
14441444+ @
14451445+ match t.multiscales with
14461446+ | Some _ -> [ Conv.Multiscales.meta ]
14471447+ | None -> []
12771448 in
12781449 if conv_metas <> [] then begin
12791450 match Jsont.Json.encode (Jsont.list Conv.Meta.jsont) conv_metas with
···12841455 emit_prefixed "spatial:" Conv.Spatial.jsont t.spatial add;
12851456 (* multiscales *)
12861457 (match t.multiscales with
12871287- | Some m ->
12881288- (match Jsont.Json.encode Conv.Multiscales.jsont m with
14581458+ | Some m -> (
14591459+ match Jsont.Json.encode Conv.Multiscales.jsont m with
12891460 | Ok j -> add (("multiscales", Jsont.Meta.none), j)
12901461 | _ -> ())
12911291- | None -> ());
14621462+ | None -> ());
12921463 emit_prefixed "geoemb:" Conv.Geoemb.jsont t.geoemb add;
12931464 (* unknown *)
12941465 (match t.unknown with
12951295- | Jsont.Object (unk_mems, _) -> List.iter add unk_mems
12961296- | _ -> ());
14661466+ | Jsont.Object (unk_mems, _) -> List.iter add unk_mems
14671467+ | _ -> ());
12971468 Jsont.Json.object' (List.rev !mems))
12981469 Jsont.json
12991470···13031474 attrs : Attrs.t;
13041475 unknown : Jsont.json;
13051476 }
14771477+13061478 let kind t = t.kind
13071479 let attrs t = t.attrs
13081480 let unknown t = t.unknown
···13141486 attrs : Attrs.t;
13151487 unknown : Jsont.json;
13161488 }
14891489+13171490 let kind t = t.kind
13181491 let attrs t = t.attrs
13191492 let unknown t = t.unknown
···13221495let v2_array_jsont : V2_node.t Jsont.t =
13231496 Jsont.map ~kind:"V2.Array"
13241497 ~dec:(fun meta ->
13251325- V2_node.{
13261326- kind = `Array meta;
13271327- attrs = Attrs.empty;
13281328- unknown = Jsont.Json.object' [];
13291329- })
14981498+ V2_node.
14991499+ {
15001500+ kind = `Array meta;
15011501+ attrs = Attrs.empty;
15021502+ unknown = Jsont.Json.object' [];
15031503+ })
13301504 ~enc:(fun t ->
13311505 match t.V2_node.kind with
13321506 | `Array a -> a
13331333- | `Group -> Jsont.Error.msgf Jsont.Meta.none "v2_array_jsont: not an array")
15071507+ | `Group ->
15081508+ Jsont.Error.msgf Jsont.Meta.none "v2_array_jsont: not an array")
13341509 V2.array_meta_jsont
1335151013361511let v2_group_jsont : V2_node.t Jsont.t =
13371512 Jsont.map ~kind:"V2.Group"
13381513 ~dec:(fun _json ->
13391339- V2_node.{
13401340- kind = `Group;
13411341- attrs = Attrs.empty;
13421342- unknown = Jsont.Json.object' [];
13431343- })
15141514+ V2_node.
15151515+ { kind = `Group; attrs = Attrs.empty; unknown = Jsont.Json.object' [] })
13441516 ~enc:(fun _t ->
13451345- Jsont.Json.object' [
13461346- (("zarr_format", Jsont.Meta.none), Jsont.Json.number 2.0);
13471347- ])
15171517+ Jsont.Json.object'
15181518+ [ (("zarr_format", Jsont.Meta.none), Jsont.Json.number 2.0) ])
13481519 Jsont.json
1349152013501521let v3_jsont : V3_node.t Jsont.t =
···13531524 in
13541525 Jsont.map ~kind:"V3.Node"
13551526 ~dec:(fun json ->
13561356- let mems = match json with
15271527+ let mems =
15281528+ match json with
13571529 | Jsont.Object (m, _) -> m
13581530 | _ -> Jsont.Error.msgf Jsont.Meta.none "v3_jsont: expected object"
13591531 in
13601360- let node_type = match find_mem mems "node_type" with
15321532+ let node_type =
15331533+ match find_mem mems "node_type" with
13611534 | Some (Jsont.String (s, _)) -> s
13621535 | _ -> Jsont.Error.msgf Jsont.Meta.none "v3_jsont: missing node_type"
13631536 in
13641537 let attrs_val =
13651538 match find_mem mems "attributes" with
13661366- | Some attrs_json ->
13671367- (match Jsont.Json.decode attrs_jsont attrs_json with
13681368- | Ok a -> a
13691369- | Error _ -> Attrs.empty)
15391539+ | Some attrs_json -> (
15401540+ match Jsont.Json.decode attrs_jsont attrs_json with
15411541+ | Ok a -> a
15421542+ | Error _ -> Attrs.empty)
13701543 | None -> Attrs.empty
13711544 in
13721545 (* unknown: everything except the standard V3 node-level keys *)
13731373- let standard_keys = [
13741374- "zarr_format"; "node_type"; "shape"; "data_type";
13751375- "chunk_grid"; "chunk_key_encoding"; "codecs"; "fill_value";
13761376- "dimension_names"; "storage_transformers"; "attributes";
13771377- ] in
13781378- let unknown_mems = List.filter
13791379- (fun ((k, _), _) -> not (List.mem k standard_keys)) mems
15461546+ let standard_keys =
15471547+ [
15481548+ "zarr_format";
15491549+ "node_type";
15501550+ "shape";
15511551+ "data_type";
15521552+ "chunk_grid";
15531553+ "chunk_key_encoding";
15541554+ "codecs";
15551555+ "fill_value";
15561556+ "dimension_names";
15571557+ "storage_transformers";
15581558+ "attributes";
15591559+ ]
15601560+ in
15611561+ let unknown_mems =
15621562+ List.filter (fun ((k, _), _) -> not (List.mem k standard_keys)) mems
13801563 in
13811564 let unknown_val = Jsont.Json.object' unknown_mems in
13821382- (match node_type with
13831383- | "array" ->
13841384- let arr = jdec V3.array_meta_jsont json in
13851385- V3_node.{ kind = `Array arr; attrs = attrs_val; unknown = unknown_val }
13861386- | "group" ->
13871387- V3_node.{ kind = `Group; attrs = attrs_val; unknown = unknown_val }
13881388- | s -> Jsont.Error.msgf Jsont.Meta.none "v3_jsont: unknown node_type: %s" s))
15651565+ match node_type with
15661566+ | "array" ->
15671567+ let arr = jdec V3.array_meta_jsont json in
15681568+ V3_node.
15691569+ { kind = `Array arr; attrs = attrs_val; unknown = unknown_val }
15701570+ | "group" ->
15711571+ V3_node.{ kind = `Group; attrs = attrs_val; unknown = unknown_val }
15721572+ | s ->
15731573+ Jsont.Error.msgf Jsont.Meta.none "v3_jsont: unknown node_type: %s" s)
13891574 ~enc:(fun (t : V3_node.t) ->
13901575 let attrs_json = jenc attrs_jsont t.attrs in
13911391- let has_attrs = match attrs_json with
13921392- | Jsont.Object ([], _) -> false
13931393- | _ -> true
15761576+ let has_attrs =
15771577+ match attrs_json with Jsont.Object ([], _) -> false | _ -> true
13941578 in
13951579 match t.kind with
13961580 | `Array a ->
13971397- let arr_json = jenc V3.array_meta_jsont a in
13981398- let arr_mems = match arr_json with
13991399- | Jsont.Object (m, _) -> m
14001400- | _ -> []
14011401- in
14021402- let mems = if has_attrs then
14031403- arr_mems @ [(("attributes", Jsont.Meta.none), attrs_json)]
14041404- else arr_mems
14051405- in
14061406- Jsont.Json.object' mems
15811581+ let arr_json = jenc V3.array_meta_jsont a in
15821582+ let arr_mems =
15831583+ match arr_json with Jsont.Object (m, _) -> m | _ -> []
15841584+ in
15851585+ let mems =
15861586+ if has_attrs then
15871587+ arr_mems @ [ (("attributes", Jsont.Meta.none), attrs_json) ]
15881588+ else arr_mems
15891589+ in
15901590+ Jsont.Json.object' mems
14071591 | `Group ->
14081408- let mems = [
14091409- (("zarr_format", Jsont.Meta.none), Jsont.Json.number 3.0);
14101410- (("node_type", Jsont.Meta.none), Jsont.Json.string "group");
14111411- ] in
14121412- let mems = if has_attrs then
14131413- mems @ [(("attributes", Jsont.Meta.none), attrs_json)]
14141414- else mems
14151415- in
14161416- Jsont.Json.object' mems)
15921592+ let mems =
15931593+ [
15941594+ (("zarr_format", Jsont.Meta.none), Jsont.Json.number 3.0);
15951595+ (("node_type", Jsont.Meta.none), Jsont.Json.string "group");
15961596+ ]
15971597+ in
15981598+ let mems =
15991599+ if has_attrs then
16001600+ mems @ [ (("attributes", Jsont.Meta.none), attrs_json) ]
16011601+ else mems
16021602+ in
16031603+ Jsont.Json.object' mems)
14171604 Jsont.json
1418160514191606type t = [ `V2 of V2_node.t | `V3 of V3_node.t ]
1420160714211608let jsont : t Jsont.t =
14221609 let find_zarr_format mems =
14231423- List.find_map (fun ((n, _), v) ->
14241424- if n = "zarr_format" then
14251425- match v with
14261426- | Jsont.Number (f, _) -> Some (int_of_float f)
14271427- | _ -> None
14281428- else None) mems
16101610+ List.find_map
16111611+ (fun ((n, _), v) ->
16121612+ if n = "zarr_format" then
16131613+ match v with
16141614+ | Jsont.Number (f, _) -> Some (int_of_float f)
16151615+ | _ -> None
16161616+ else None)
16171617+ mems
14291618 in
14301430- let has_shape mems =
14311431- List.exists (fun ((k, _), _) -> k = "shape") mems
14321432- in
16191619+ let has_shape mems = List.exists (fun ((k, _), _) -> k = "shape") mems in
14331620 Jsont.map ~kind:"Zarr"
14341621 ~dec:(fun json ->
14351435- let mems = match json with
16221622+ let mems =
16231623+ match json with
14361624 | Jsont.Object (m, _) -> m
14371625 | _ -> Jsont.Error.msgf Jsont.Meta.none "jsont: expected object"
14381626 in
14391439- let zarr_format = match find_zarr_format mems with
16271627+ let zarr_format =
16281628+ match find_zarr_format mems with
14401629 | Some n -> n
14411630 | None -> Jsont.Error.msgf Jsont.Meta.none "jsont: missing zarr_format"
14421631 in
14431632 match zarr_format with
14441633 | 2 ->
14451445- if has_shape mems then `V2 (jdec v2_array_jsont json)
14461446- else `V2 (jdec v2_group_jsont json)
16341634+ if has_shape mems then `V2 (jdec v2_array_jsont json)
16351635+ else `V2 (jdec v2_group_jsont json)
14471636 | 3 -> `V3 (jdec v3_jsont json)
14481637 | n -> Jsont.Error.msgf Jsont.Meta.none "jsont: unknown zarr_format: %d" n)
14491638 ~enc:(function
14501450- | `V2 node ->
14511451- (match V2_node.kind node with
14521452- | `Array _ -> jenc v2_array_jsont node
14531453- | `Group -> jenc v2_group_jsont node)
16391639+ | `V2 node -> (
16401640+ match V2_node.kind node with
16411641+ | `Array _ -> jenc v2_array_jsont node
16421642+ | `Group -> jenc v2_group_jsont node)
14541643 | `V3 node -> jenc v3_jsont node)
14551644 Jsont.json
1456164514571646(* Consolidated metadata — V3 *)
1458164714591648module Consolidated = struct
14601460- type t = {
14611461- metadata : (string * V3_node.t) list;
14621462- kind : string;
14631463- }
16491649+ type t = { metadata : (string * V3_node.t) list; kind : string }
16501650+14641651 let metadata t = t.metadata
14651652 let kind t = t.kind
14661653···14681655 (* consolidated_metadata is an object with "metadata", "kind", "must_understand" *)
14691656 Jsont.map ~kind:"Consolidated"
14701657 ~dec:(fun json ->
14711471- let mems = match json with
16581658+ let mems =
16591659+ match json with
14721660 | Jsont.Object (mems, _) -> mems
14731473- | _ -> Jsont.Error.msgf Jsont.Meta.none "Consolidated: expected object"
16611661+ | _ ->
16621662+ Jsont.Error.msgf Jsont.Meta.none "Consolidated: expected object"
14741663 in
14751475- let find k = List.find_map (fun ((n, _), v) ->
14761476- if n = k then Some v else None) mems
16641664+ let find k =
16651665+ List.find_map (fun ((n, _), v) -> if n = k then Some v else None) mems
14771666 in
14781478- let kind = match find "kind" with
14791479- | Some (Jsont.String (s, _)) -> s | _ -> "inline"
16671667+ let kind =
16681668+ match find "kind" with
16691669+ | Some (Jsont.String (s, _)) -> s
16701670+ | _ -> "inline"
14801671 in
14811481- let metadata = match find "metadata" with
16721672+ let metadata =
16731673+ match find "metadata" with
14821674 | Some (Jsont.Object (entries, _)) ->
14831483- List.filter_map (fun ((path, _), node_json) ->
14841484- match Jsont.Json.decode v3_jsont node_json with
14851485- | Ok node -> Some (path, node)
14861486- | Error _ -> None) entries
16751675+ List.filter_map
16761676+ (fun ((path, _), node_json) ->
16771677+ match Jsont.Json.decode v3_jsont node_json with
16781678+ | Ok node -> Some (path, node)
16791679+ | Error _ -> None)
16801680+ entries
14871681 | _ -> []
14881682 in
14891683 { metadata; kind })
14901684 ~enc:(fun t ->
14911491- let entries = List.map (fun (path, node) ->
14921492- ((path, Jsont.Meta.none), jenc v3_jsont node)) t.metadata
16851685+ let entries =
16861686+ List.map
16871687+ (fun (path, node) -> ((path, Jsont.Meta.none), jenc v3_jsont node))
16881688+ t.metadata
14931689 in
14941494- Jsont.Json.object' [
14951495- (("metadata", Jsont.Meta.none), Jsont.Object (entries, Jsont.Meta.none));
14961496- (("kind", Jsont.Meta.none), Jsont.Json.string t.kind);
14971497- (("must_understand", Jsont.Meta.none), Jsont.Json.bool false);
14981498- ])
16901690+ Jsont.Json.object'
16911691+ [
16921692+ ( ("metadata", Jsont.Meta.none),
16931693+ Jsont.Object (entries, Jsont.Meta.none) );
16941694+ (("kind", Jsont.Meta.none), Jsont.Json.string t.kind);
16951695+ (("must_understand", Jsont.Meta.none), Jsont.Json.bool false);
16961696+ ])
14991697 Jsont.json
15001698end
1501169915021700(* Consolidated metadata — V2 (.zmetadata) *)
1503170115041702module V2_consolidated = struct
15051505- type entry = {
15061506- path : string;
15071507- node : V2_node.t;
15081508- attrs : Attrs.t option;
15091509- }
17031703+ type entry = { path : string; node : V2_node.t; attrs : Attrs.t option }
17041704+ type t = { entries : entry list; format_version : int }
1510170515111511- type t = {
15121512- entries : entry list;
15131513- format_version : int;
15141514- }
15151706 let entries t = t.entries
15161707 let format_version t = t.format_version
15171708···15191710 (* .zmetadata: {"metadata": {"path/.zarray": {...}, ...}, "zarr_consolidated_format": 1} *)
15201711 Jsont.map ~kind:"V2_consolidated"
15211712 ~dec:(fun json ->
15221522- let mems = match json with
17131713+ let mems =
17141714+ match json with
15231715 | Jsont.Object (mems, _) -> mems
15241524- | _ -> Jsont.Error.msgf Jsont.Meta.none "V2_consolidated: expected object"
17161716+ | _ ->
17171717+ Jsont.Error.msgf Jsont.Meta.none
17181718+ "V2_consolidated: expected object"
15251719 in
15261526- let find k = List.find_map (fun ((n, _), v) ->
15271527- if n = k then Some v else None) mems
17201720+ let find k =
17211721+ List.find_map (fun ((n, _), v) -> if n = k then Some v else None) mems
15281722 in
15291529- let format_version = match find "zarr_consolidated_format" with
15301530- | Some (Jsont.Number (f, _)) -> int_of_float f | _ -> 1
17231723+ let format_version =
17241724+ match find "zarr_consolidated_format" with
17251725+ | Some (Jsont.Number (f, _)) -> int_of_float f
17261726+ | _ -> 1
15311727 in
15321532- let metadata = match find "metadata" with
17281728+ let metadata =
17291729+ match find "metadata" with
15331730 | Some (Jsont.Object (entries, _)) -> entries
15341731 | _ -> []
15351732 in
15361733 (* Group entries by path prefix: collect .zarray/.zgroup and .zattrs *)
15371734 let tbl = Hashtbl.create 16 in
15381538- List.iter (fun ((key, _), value) ->
15391539- (* key is like "array1/.zarray" or "array1/.zattrs" or ".zgroup" *)
15401540- let parts = match String.rindex_opt key '/' with
15411541- | Some i -> (String.sub key 0 i, String.sub key (i + 1) (String.length key - i - 1))
15421542- | None -> ("", key)
15431543- in
15441544- let (prefix, basename) = parts in
15451545- let (node_json, attrs_json) =
15461546- match Hashtbl.find_opt tbl prefix with
15471547- | Some v -> v | None -> (None, None)
15481548- in
15491549- let v = match basename with
15501550- | ".zarray" | ".zgroup" -> (Some value, attrs_json)
15511551- | ".zattrs" -> (node_json, Some value)
15521552- | _ -> (node_json, attrs_json)
15531553- in
15541554- Hashtbl.replace tbl prefix v
15551555- ) metadata;
15561556- let entries = Hashtbl.fold (fun path (node_json, attrs_json) acc ->
15571557- let node = match node_json with
15581558- | Some nj ->
15591559- (match Jsont.Json.decode v2_array_jsont nj with
15601560- | Ok n -> Some n
15611561- | Error _ ->
15621562- match Jsont.Json.decode v2_group_jsont nj with
15631563- | Ok n -> Some n | Error _ -> None)
15641564- | None -> None
15651565- in
15661566- let attrs = match attrs_json with
15671567- | Some aj ->
15681568- (match Jsont.Json.decode attrs_jsont aj with
15691569- | Ok a -> Some a | Error _ -> None)
15701570- | None -> None
15711571- in
15721572- match node with
15731573- | Some n -> { path; node = n; attrs } :: acc
15741574- | None -> acc
15751575- ) tbl [] in
15761576- let entries = List.sort (fun a b -> String.compare a.path b.path) entries in
17351735+ List.iter
17361736+ (fun ((key, _), value) ->
17371737+ (* key is like "array1/.zarray" or "array1/.zattrs" or ".zgroup" *)
17381738+ let parts =
17391739+ match String.rindex_opt key '/' with
17401740+ | Some i ->
17411741+ ( String.sub key 0 i,
17421742+ String.sub key (i + 1) (String.length key - i - 1) )
17431743+ | None -> ("", key)
17441744+ in
17451745+ let prefix, basename = parts in
17461746+ let node_json, attrs_json =
17471747+ match Hashtbl.find_opt tbl prefix with
17481748+ | Some v -> v
17491749+ | None -> (None, None)
17501750+ in
17511751+ let v =
17521752+ match basename with
17531753+ | ".zarray" | ".zgroup" -> (Some value, attrs_json)
17541754+ | ".zattrs" -> (node_json, Some value)
17551755+ | _ -> (node_json, attrs_json)
17561756+ in
17571757+ Hashtbl.replace tbl prefix v)
17581758+ metadata;
17591759+ let entries =
17601760+ Hashtbl.fold
17611761+ (fun path (node_json, attrs_json) acc ->
17621762+ let node =
17631763+ match node_json with
17641764+ | Some nj -> (
17651765+ match Jsont.Json.decode v2_array_jsont nj with
17661766+ | Ok n -> Some n
17671767+ | Error _ -> (
17681768+ match Jsont.Json.decode v2_group_jsont nj with
17691769+ | Ok n -> Some n
17701770+ | Error _ -> None))
17711771+ | None -> None
17721772+ in
17731773+ let attrs =
17741774+ match attrs_json with
17751775+ | Some aj -> (
17761776+ match Jsont.Json.decode attrs_jsont aj with
17771777+ | Ok a -> Some a
17781778+ | Error _ -> None)
17791779+ | None -> None
17801780+ in
17811781+ match node with
17821782+ | Some n -> { path; node = n; attrs } :: acc
17831783+ | None -> acc)
17841784+ tbl []
17851785+ in
17861786+ let entries =
17871787+ List.sort (fun a b -> String.compare a.path b.path) entries
17881788+ in
15771789 { entries; format_version })
15781790 ~enc:(fun t ->
15791579- let metadata_entries = List.concat_map (fun entry ->
15801580- let prefix = if entry.path = "" then "" else entry.path ^ "/" in
15811581- let node_entries = match V2_node.kind entry.node with
15821582- | `Array a ->
15831583- (match Jsont.Json.encode V2.array_meta_jsont a with
15841584- | Ok j -> [((prefix ^ ".zarray", Jsont.Meta.none), j)]
15851585- | Error _ -> [])
15861586- | `Group ->
15871587- [((prefix ^ ".zgroup", Jsont.Meta.none),
15881588- Jsont.Json.object' [(("zarr_format", Jsont.Meta.none), Jsont.Json.number 2.0)])]
15891589- in
15901590- let attrs_entries = match entry.attrs with
15911591- | Some a ->
15921592- (match Jsont.Json.encode attrs_jsont a with
15931593- | Ok j -> [((prefix ^ ".zattrs", Jsont.Meta.none), j)]
15941594- | Error _ -> [])
15951595- | None -> []
15961596- in
15971597- node_entries @ attrs_entries
15981598- ) t.entries in
15991599- Jsont.Json.object' [
16001600- (("metadata", Jsont.Meta.none), Jsont.Object (metadata_entries, Jsont.Meta.none));
16011601- (("zarr_consolidated_format", Jsont.Meta.none), Jsont.Json.number (float_of_int t.format_version));
16021602- ])
17911791+ let metadata_entries =
17921792+ List.concat_map
17931793+ (fun entry ->
17941794+ let prefix = if entry.path = "" then "" else entry.path ^ "/" in
17951795+ let node_entries =
17961796+ match V2_node.kind entry.node with
17971797+ | `Array a -> (
17981798+ match Jsont.Json.encode V2.array_meta_jsont a with
17991799+ | Ok j -> [ ((prefix ^ ".zarray", Jsont.Meta.none), j) ]
18001800+ | Error _ -> [])
18011801+ | `Group ->
18021802+ [
18031803+ ( (prefix ^ ".zgroup", Jsont.Meta.none),
18041804+ Jsont.Json.object'
18051805+ [
18061806+ ( ("zarr_format", Jsont.Meta.none),
18071807+ Jsont.Json.number 2.0 );
18081808+ ] );
18091809+ ]
18101810+ in
18111811+ let attrs_entries =
18121812+ match entry.attrs with
18131813+ | Some a -> (
18141814+ match Jsont.Json.encode attrs_jsont a with
18151815+ | Ok j -> [ ((prefix ^ ".zattrs", Jsont.Meta.none), j) ]
18161816+ | Error _ -> [])
18171817+ | None -> []
18181818+ in
18191819+ node_entries @ attrs_entries)
18201820+ t.entries
18211821+ in
18221822+ Jsont.Json.object'
18231823+ [
18241824+ ( ("metadata", Jsont.Meta.none),
18251825+ Jsont.Object (metadata_entries, Jsont.Meta.none) );
18261826+ ( ("zarr_consolidated_format", Jsont.Meta.none),
18271827+ Jsont.Json.number (float_of_int t.format_version) );
18281828+ ])
16031829 Jsont.json
16041830end
16051831···16121838 children : (string * probe_result) list;
16131839}
1614184016151615-let decode_string codec s =
16161616- Jsont_bytesrw.decode_string codec s
18411841+let decode_string codec s = Jsont_bytesrw.decode_string codec s
1617184216181843let try_v3_consolidated contents =
16191844 match Jsont_bytesrw.decode_string Jsont.json contents with
16201845 | Ok (Jsont.Object (mems, _)) ->
16211621- List.find_map (fun ((k, _), v) ->
16221622- if k = "consolidated_metadata" then
16231623- match Jsont.Json.decode Consolidated.jsont v with
16241624- | Ok c -> Some c | Error _ -> None
16251625- else None) mems
18461846+ List.find_map
18471847+ (fun ((k, _), v) ->
18481848+ if k = "consolidated_metadata" then
18491849+ match Jsont.Json.decode Consolidated.jsont v with
18501850+ | Ok c -> Some c
18511851+ | Error _ -> None
18521852+ else None)
18531853+ mems
16261854 | _ -> None
1627185516281856(* Build children tree from consolidated metadata *)
16291857let rec children_of_v3_consolidated (c : Consolidated.t) =
16301858 let immediate = Hashtbl.create 16 in
16311631- List.iter (fun (path, node) ->
16321632- let top, rest = match String.index_opt path '/' with
16331633- | Some i ->
16341634- String.sub path 0 i,
16351635- Some (String.sub path (i + 1) (String.length path - i - 1), node)
16361636- | None -> path, None
16371637- in
16381638- let (direct, nested) = match Hashtbl.find_opt immediate top with
16391639- | Some v -> v | None -> (None, [])
16401640- in
16411641- match rest with
16421642- | None -> Hashtbl.replace immediate top (Some node, nested)
16431643- | Some sub -> Hashtbl.replace immediate top (direct, sub :: nested)
16441644- ) (Consolidated.metadata c);
16451645- Hashtbl.fold (fun name (direct, nested) acc ->
16461646- let node = match direct with
16471647- | Some n -> n
16481648- | None ->
16491649- V3_node.{ kind = `Group; attrs = Attrs.empty;
16501650- unknown = Jsont.Json.object' [] }
16511651- in
16521652- let children = match V3_node.kind node, nested with
16531653- | `Group, _ :: _ ->
16541654- let sub_c = { Consolidated.metadata = List.rev nested;
16551655- kind = c.kind } in
16561656- children_of_v3_consolidated sub_c
16571657- | _ -> []
16581658- in
16591659- (name, { node = `V3 node; attrs = None;
16601660- consolidated = None; children }) :: acc
16611661- ) immediate []
18591859+ List.iter
18601860+ (fun (path, node) ->
18611861+ let top, rest =
18621862+ match String.index_opt path '/' with
18631863+ | Some i ->
18641864+ ( String.sub path 0 i,
18651865+ Some (String.sub path (i + 1) (String.length path - i - 1), node)
18661866+ )
18671867+ | None -> (path, None)
18681868+ in
18691869+ let direct, nested =
18701870+ match Hashtbl.find_opt immediate top with
18711871+ | Some v -> v
18721872+ | None -> (None, [])
18731873+ in
18741874+ match rest with
18751875+ | None -> Hashtbl.replace immediate top (Some node, nested)
18761876+ | Some sub -> Hashtbl.replace immediate top (direct, sub :: nested))
18771877+ (Consolidated.metadata c);
18781878+ Hashtbl.fold
18791879+ (fun name (direct, nested) acc ->
18801880+ let node =
18811881+ match direct with
18821882+ | Some n -> n
18831883+ | None ->
18841884+ V3_node.
18851885+ {
18861886+ kind = `Group;
18871887+ attrs = Attrs.empty;
18881888+ unknown = Jsont.Json.object' [];
18891889+ }
18901890+ in
18911891+ let children =
18921892+ match (V3_node.kind node, nested) with
18931893+ | `Group, _ :: _ ->
18941894+ let sub_c =
18951895+ { Consolidated.metadata = List.rev nested; kind = c.kind }
18961896+ in
18971897+ children_of_v3_consolidated sub_c
18981898+ | _ -> []
18991899+ in
19001900+ (name, { node = `V3 node; attrs = None; consolidated = None; children })
19011901+ :: acc)
19021902+ immediate []
16621903 |> List.sort (fun (a, _) (b, _) -> String.compare a b)
1663190416641905and children_of_v2_consolidated (c : V2_consolidated.t) =
16651906 (* Build tree: group entries by top-level path component *)
16661907 let immediate = Hashtbl.create 16 in
16671667- List.iter (fun ({ V2_consolidated.path; _ } as entry) ->
16681668- if path <> "" then begin
16691669- let top, is_direct = match String.index_opt path '/' with
16701670- | Some i -> String.sub path 0 i, false
16711671- | None -> path, true
19081908+ List.iter
19091909+ (fun ({ V2_consolidated.path; _ } as entry) ->
19101910+ if path <> "" then begin
19111911+ let top, is_direct =
19121912+ match String.index_opt path '/' with
19131913+ | Some i -> (String.sub path 0 i, false)
19141914+ | None -> (path, true)
19151915+ in
19161916+ let direct, nested =
19171917+ match Hashtbl.find_opt immediate top with
19181918+ | Some v -> v
19191919+ | None -> (None, [])
19201920+ in
19211921+ if is_direct then Hashtbl.replace immediate top (Some entry, nested)
19221922+ else
19231923+ let rest_path =
19241924+ match String.index_opt path '/' with
19251925+ | Some i -> String.sub path (i + 1) (String.length path - i - 1)
19261926+ | None -> path
19271927+ in
19281928+ Hashtbl.replace immediate top
19291929+ (direct, { entry with path = rest_path } :: nested)
19301930+ end)
19311931+ (V2_consolidated.entries c);
19321932+ Hashtbl.fold
19331933+ (fun name (direct, nested) acc ->
19341934+ let node, attrs =
19351935+ match direct with
19361936+ | Some e -> (e.V2_consolidated.node, e.V2_consolidated.attrs)
19371937+ | None ->
19381938+ ( V2_node.
19391939+ {
19401940+ kind = `Group;
19411941+ attrs = Attrs.empty;
19421942+ unknown = Jsont.Json.object' [];
19431943+ },
19441944+ None )
16721945 in
16731673- let (direct, nested) = match Hashtbl.find_opt immediate top with
16741674- | Some v -> v | None -> (None, [])
19461946+ let children =
19471947+ match nested with
19481948+ | [] -> []
19491949+ | _ ->
19501950+ let sub_c =
19511951+ {
19521952+ V2_consolidated.entries = List.rev nested;
19531953+ format_version = V2_consolidated.format_version c;
19541954+ }
19551955+ in
19561956+ children_of_v2_consolidated sub_c
16751957 in
16761676- if is_direct then
16771677- Hashtbl.replace immediate top (Some entry, nested)
16781678- else
16791679- let rest_path = match String.index_opt path '/' with
16801680- | Some i -> String.sub path (i + 1) (String.length path - i - 1)
16811681- | None -> path
16821682- in
16831683- Hashtbl.replace immediate top
16841684- (direct, { entry with path = rest_path } :: nested)
16851685- end
16861686- ) (V2_consolidated.entries c);
16871687- Hashtbl.fold (fun name (direct, nested) acc ->
16881688- let node, attrs = match direct with
16891689- | Some e -> e.V2_consolidated.node, e.V2_consolidated.attrs
16901690- | None ->
16911691- V2_node.{ kind = `Group; attrs = Attrs.empty;
16921692- unknown = Jsont.Json.object' [] }, None
16931693- in
16941694- let children = match nested with
16951695- | [] -> []
16961696- | _ ->
16971697- let sub_c = { V2_consolidated.entries = List.rev nested;
16981698- format_version = V2_consolidated.format_version c } in
16991699- children_of_v2_consolidated sub_c
17001700- in
17011701- (name, { node = `V2 node; attrs;
17021702- consolidated = None; children }) :: acc
17031703- ) immediate []
19581958+ (name, { node = `V2 node; attrs; consolidated = None; children }) :: acc)
19591959+ immediate []
17041960 |> List.sort (fun (a, _) (b, _) -> String.compare a b)
1705196117061962let read_v2_attrs read_rel =
17071963 match read_rel ".zattrs" with
17081708- | Ok a -> (match decode_string attrs_jsont a with Ok a -> Some a | Error _ -> None)
19641964+ | Ok a -> (
19651965+ match decode_string attrs_jsont a with Ok a -> Some a | Error _ -> None)
17091966 | Error _ -> None
1710196717111968let probe ~read path =
17121969 let read_rel = read in
17131970 (* Try v3 first *)
17141971 match read_rel "zarr.json" with
17151715- | Ok contents ->
17161716- (match decode_string v3_jsont contents with
17171717- | Ok node ->
17181718- let consolidated = Option.map (fun c -> `V3 c)
17191719- (try_v3_consolidated contents) in
17201720- let children = match consolidated with
17211721- | Some (`V3 c) -> children_of_v3_consolidated c
17221722- | _ -> []
17231723- in
17241724- Ok { node = `V3 node; attrs = None; consolidated; children }
17251725- | Error e -> Error (Printf.sprintf "zarr.json: %s" e))
17261726- | Error _ ->
17271727- match read_rel ".zarray" with
17281728- | Ok contents ->
17291729- (match decode_string v2_array_jsont contents with
17301730- | Ok node ->
17311731- let attrs = read_v2_attrs read_rel in
17321732- Ok { node = `V2 node; attrs; consolidated = None; children = [] }
17331733- | Error e -> Error (Printf.sprintf ".zarray: %s" e))
17341734- | Error _ ->
17351735- match read_rel ".zgroup" with
17361736- | Ok contents ->
17371737- (match decode_string v2_group_jsont contents with
17381738- | Ok node ->
17391739- let attrs = read_v2_attrs read_rel in
17401740- let consolidated = match read_rel ".zmetadata" with
17411741- | Ok mc ->
17421742- (match decode_string V2_consolidated.jsont mc with
17431743- | Ok c -> Some (`V2 c) | Error _ -> None)
17441744- | Error _ -> None
17451745- in
17461746- let children = match consolidated with
17471747- | Some (`V2 c) -> children_of_v2_consolidated c
17481748- | _ -> []
17491749- in
17501750- Ok { node = `V2 node; attrs; consolidated; children }
17511751- | Error e -> Error (Printf.sprintf ".zgroup: %s" e))
17521752- | Error _ ->
17531753- match read_rel ".zmetadata" with
17541754- | Ok mc ->
17551755- (match decode_string V2_consolidated.jsont mc with
17561756- | Ok c ->
17571757- let node = V2_node.{ kind = `Group; attrs = Attrs.empty;
17581758- unknown = Jsont.Json.object' [] } in
17591759- let attrs = read_v2_attrs read_rel in
17601760- let children = children_of_v2_consolidated c in
17611761- Ok { node = `V2 node; attrs; consolidated = Some (`V2 c); children }
17621762- | Error e -> Error (Printf.sprintf ".zmetadata: %s" e))
17631763- | Error _ ->
17641764- Error (Printf.sprintf
17651765- "%s: no zarr metadata found (tried zarr.json, .zarray, .zgroup, .zmetadata)"
17661766- path)
19721972+ | Ok contents -> (
19731973+ match decode_string v3_jsont contents with
19741974+ | Ok node ->
19751975+ let consolidated =
19761976+ Option.map (fun c -> `V3 c) (try_v3_consolidated contents)
19771977+ in
19781978+ let children =
19791979+ match consolidated with
19801980+ | Some (`V3 c) -> children_of_v3_consolidated c
19811981+ | _ -> []
19821982+ in
19831983+ Ok { node = `V3 node; attrs = None; consolidated; children }
19841984+ | Error e -> Error (Printf.sprintf "zarr.json: %s" e))
19851985+ | Error _ -> (
19861986+ match read_rel ".zarray" with
19871987+ | Ok contents -> (
19881988+ match decode_string v2_array_jsont contents with
19891989+ | Ok node ->
19901990+ let attrs = read_v2_attrs read_rel in
19911991+ Ok { node = `V2 node; attrs; consolidated = None; children = [] }
19921992+ | Error e -> Error (Printf.sprintf ".zarray: %s" e))
19931993+ | Error _ -> (
19941994+ match read_rel ".zgroup" with
19951995+ | Ok contents -> (
19961996+ match decode_string v2_group_jsont contents with
19971997+ | Ok node ->
19981998+ let attrs = read_v2_attrs read_rel in
19991999+ let consolidated =
20002000+ match read_rel ".zmetadata" with
20012001+ | Ok mc -> (
20022002+ match decode_string V2_consolidated.jsont mc with
20032003+ | Ok c -> Some (`V2 c)
20042004+ | Error _ -> None)
20052005+ | Error _ -> None
20062006+ in
20072007+ let children =
20082008+ match consolidated with
20092009+ | Some (`V2 c) -> children_of_v2_consolidated c
20102010+ | _ -> []
20112011+ in
20122012+ Ok { node = `V2 node; attrs; consolidated; children }
20132013+ | Error e -> Error (Printf.sprintf ".zgroup: %s" e))
20142014+ | Error _ -> (
20152015+ match read_rel ".zmetadata" with
20162016+ | Ok mc -> (
20172017+ match decode_string V2_consolidated.jsont mc with
20182018+ | Ok c ->
20192019+ let node =
20202020+ V2_node.
20212021+ {
20222022+ kind = `Group;
20232023+ attrs = Attrs.empty;
20242024+ unknown = Jsont.Json.object' [];
20252025+ }
20262026+ in
20272027+ let attrs = read_v2_attrs read_rel in
20282028+ let children = children_of_v2_consolidated c in
20292029+ Ok
20302030+ {
20312031+ node = `V2 node;
20322032+ attrs;
20332033+ consolidated = Some (`V2 c);
20342034+ children;
20352035+ }
20362036+ | Error e -> Error (Printf.sprintf ".zmetadata: %s" e))
20372037+ | Error _ ->
20382038+ Error
20392039+ (Printf.sprintf
20402040+ "%s: no zarr metadata found (tried zarr.json, .zarray, \
20412041+ .zgroup, .zmetadata)"
20422042+ path))))
1767204317682044(* Pretty-printing *)
17692045···17832059 | `Structured _ -> pf ppf "structured"
1784206017852061let pp_data_type ppf = function
17861786- | `Bool -> pf ppf "bool" | `Int8 -> pf ppf "int8"
17871787- | `Int16 -> pf ppf "int16" | `Int32 -> pf ppf "int32"
17881788- | `Int64 -> pf ppf "int64" | `Uint8 -> pf ppf "uint8"
17891789- | `Uint16 -> pf ppf "uint16" | `Uint32 -> pf ppf "uint32"
17901790- | `Uint64 -> pf ppf "uint64" | `Float16 -> pf ppf "float16"
17911791- | `Float32 -> pf ppf "float32" | `Float64 -> pf ppf "float64"
17921792- | `Complex64 -> pf ppf "complex64" | `Complex128 -> pf ppf "complex128"
20622062+ | `Bool -> pf ppf "bool"
20632063+ | `Int8 -> pf ppf "int8"
20642064+ | `Int16 -> pf ppf "int16"
20652065+ | `Int32 -> pf ppf "int32"
20662066+ | `Int64 -> pf ppf "int64"
20672067+ | `Uint8 -> pf ppf "uint8"
20682068+ | `Uint16 -> pf ppf "uint16"
20692069+ | `Uint32 -> pf ppf "uint32"
20702070+ | `Uint64 -> pf ppf "uint64"
20712071+ | `Float16 -> pf ppf "float16"
20722072+ | `Float32 -> pf ppf "float32"
20732073+ | `Float64 -> pf ppf "float64"
20742074+ | `Complex64 -> pf ppf "complex64"
20752075+ | `Complex128 -> pf ppf "complex128"
17932076 | `Raw n -> pf ppf "r%d" n
17942077 | `Other o -> pf ppf "%s" (Other_ext.name o)
17952078···18022085 | `Bytes s -> pf ppf "<%d bytes>" (String.length s)
1803208618042087let pp_shape ppf shape =
18051805- Format.pp_print_list ~pp_sep:(fun ppf () -> pf ppf "x")
20882088+ Format.pp_print_list
20892089+ ~pp_sep:(fun ppf () -> pf ppf "x")
18062090 Format.pp_print_int ppf shape
1807209118082092let pp_floats ppf fs =
18091809- Format.pp_print_list ~pp_sep:(fun ppf () -> pf ppf ",")
18101810- (fun ppf f -> pf ppf "%.4g" f) ppf fs
18111811-18121812-let pp_opt pp ppf = function
18131813- | Some v -> pp ppf v
18141814- | None -> ()
18151815-18161816-let pp_labelled label pp ppf v =
18171817- pf ppf " %s=[%a]" label pp v
20932093+ Format.pp_print_list
20942094+ ~pp_sep:(fun ppf () -> pf ppf ",")
20952095+ (fun ppf f -> pf ppf "%.4g" f)
20962096+ ppf fs
1818209718191819-let node_attrs = function
18201820- | `V2 n -> V2_node.attrs n
18211821- | `V3 n -> V3_node.attrs n
20982098+let pp_opt pp ppf = function Some v -> pp ppf v | None -> ()
20992099+let pp_labelled label pp ppf v = pf ppf " %s=[%a]" label pp v
21002100+let node_attrs = function `V2 n -> V2_node.attrs n | `V3 n -> V3_node.attrs n
1822210118232102let pp_node_kind ppf = function
18241824- | `V2 n ->
18251825- (match V2_node.kind n with
18261826- | `Array a -> pf ppf "array %a %a" pp_dtype (V2.Array_meta.dtype a) pp_shape (V2.Array_meta.shape a)
18271827- | `Group -> pf ppf "group")
18281828- | `V3 n ->
18291829- (match V3_node.kind n with
18301830- | `Array a -> pf ppf "array %a %a" pp_data_type (V3.Array_meta.data_type a) pp_shape (V3.Array_meta.shape a)
18311831- | `Group -> pf ppf "group")
21032103+ | `V2 n -> (
21042104+ match V2_node.kind n with
21052105+ | `Array a ->
21062106+ pf ppf "array %a %a" pp_dtype (V2.Array_meta.dtype a) pp_shape
21072107+ (V2.Array_meta.shape a)
21082108+ | `Group -> pf ppf "group")
21092109+ | `V3 n -> (
21102110+ match V3_node.kind n with
21112111+ | `Array a ->
21122112+ pf ppf "array %a %a" pp_data_type
21132113+ (V3.Array_meta.data_type a)
21142114+ pp_shape (V3.Array_meta.shape a)
21152115+ | `Group -> pf ppf "group")
1832211618332117let rec pp_tree indent ppf children =
18341834- List.iter (fun (name, (result : probe_result)) ->
18351835- pf ppf "\n%s%s [%a]" indent name pp_node_kind result.node;
18361836- let attrs = match result.attrs with
18371837- | Some a -> a | None -> node_attrs result.node
18381838- in
18391839- pp_indented_attrs (indent ^ " ") ppf attrs;
18401840- if result.children <> [] then
18411841- pp_tree (indent ^ " ") ppf result.children
18421842- ) children
21182118+ List.iter
21192119+ (fun (name, (result : probe_result)) ->
21202120+ pf ppf "\n%s%s [%a]" indent name pp_node_kind result.node;
21212121+ let attrs =
21222122+ match result.attrs with Some a -> a | None -> node_attrs result.node
21232123+ in
21242124+ pp_indented_attrs (indent ^ " ") ppf attrs;
21252125+ if result.children <> [] then pp_tree (indent ^ " ") ppf result.children)
21262126+ children
1843212718442128and pp_indented_attrs indent ppf attrs =
18452129 let nl () = pf ppf "\n%s" indent in
18462130 (match Attrs.proj attrs with
18471847- | Some p ->
18481848- nl (); pf ppf "proj:";
18491849- Option.iter (pf ppf " code=%s") (Conv.Proj.code p);
18501850- Option.iter (fun _ -> pf ppf " wkt2=...") (Conv.Proj.wkt2 p);
18511851- Option.iter (fun _ -> pf ppf " projjson=...") (Conv.Proj.projjson p)
18521852- | None -> ());
21312131+ | Some p ->
21322132+ nl ();
21332133+ pf ppf "proj:";
21342134+ Option.iter (pf ppf " code=%s") (Conv.Proj.code p);
21352135+ Option.iter (fun _ -> pf ppf " wkt2=...") (Conv.Proj.wkt2 p);
21362136+ Option.iter (fun _ -> pf ppf " projjson=...") (Conv.Proj.projjson p)
21372137+ | None -> ());
18532138 (match Attrs.spatial attrs with
18541854- | Some s ->
18551855- nl (); pf ppf "spatial: dims=[%a]"
18561856- (Format.pp_print_list ~pp_sep:(fun ppf () -> pf ppf ",")
18571857- Format.pp_print_string) (Conv.Spatial.dimensions s);
18581858- pp_opt (pp_labelled "bbox" pp_floats) ppf (Conv.Spatial.bbox s);
18591859- pp_opt (pp_labelled "transform" pp_floats) ppf (Conv.Spatial.transform s);
18601860- pp_opt (pp_labelled "shape" pp_shape) ppf (Conv.Spatial.shape s);
18611861- (match Conv.Spatial.registration s with
18621862- | Some `Pixel -> pf ppf " reg=pixel" | Some `Node -> pf ppf " reg=node"
21392139+ | Some s -> (
21402140+ nl ();
21412141+ pf ppf "spatial: dims=[%a]"
21422142+ (Format.pp_print_list
21432143+ ~pp_sep:(fun ppf () -> pf ppf ",")
21442144+ Format.pp_print_string)
21452145+ (Conv.Spatial.dimensions s);
21462146+ pp_opt (pp_labelled "bbox" pp_floats) ppf (Conv.Spatial.bbox s);
21472147+ pp_opt (pp_labelled "transform" pp_floats) ppf (Conv.Spatial.transform s);
21482148+ pp_opt (pp_labelled "shape" pp_shape) ppf (Conv.Spatial.shape s);
21492149+ match Conv.Spatial.registration s with
21502150+ | Some `Pixel -> pf ppf " reg=pixel"
21512151+ | Some `Node -> pf ppf " reg=node"
18632152 | None -> ())
18641864- | None -> ());
21532153+ | None -> ());
18652154 (match Attrs.multiscales attrs with
18661866- | Some m ->
18671867- let layout = Conv.Multiscales.layout m in
18681868- nl (); pf ppf "multiscales: %d levels" (List.length layout);
18691869- Option.iter (pf ppf " resampling=%s") (Conv.Multiscales.resampling_method m);
18701870- List.iter (fun item ->
18711871- pf ppf "\n%s %s" indent (Conv.Multiscales.Layout_item.asset item);
18721872- Option.iter (pf ppf " <- %s") (Conv.Multiscales.Layout_item.derived_from item);
18731873- Option.iter (fun t ->
18741874- pp_opt (pp_labelled "scale" pp_floats) ppf (Conv.Multiscales.Transform.scale t)
18751875- ) (Conv.Multiscales.Layout_item.transform item)
18761876- ) layout
18771877- | None -> ());
21552155+ | Some m ->
21562156+ let layout = Conv.Multiscales.layout m in
21572157+ nl ();
21582158+ pf ppf "multiscales: %d levels" (List.length layout);
21592159+ Option.iter (pf ppf " resampling=%s")
21602160+ (Conv.Multiscales.resampling_method m);
21612161+ List.iter
21622162+ (fun item ->
21632163+ pf ppf "\n%s %s" indent (Conv.Multiscales.Layout_item.asset item);
21642164+ Option.iter (pf ppf " <- %s")
21652165+ (Conv.Multiscales.Layout_item.derived_from item);
21662166+ Option.iter
21672167+ (fun t ->
21682168+ pp_opt
21692169+ (pp_labelled "scale" pp_floats)
21702170+ ppf
21712171+ (Conv.Multiscales.Transform.scale t))
21722172+ (Conv.Multiscales.Layout_item.transform item))
21732173+ layout
21742174+ | None -> ());
18782175 (* geoemb *)
18792176 (match Attrs.geoemb attrs with
18801880- | Some g ->
18811881- let ty = match Conv.Geoemb.type_ g with `Pixel -> "pixel" | `Chip -> "chip" in
18821882- nl (); pf ppf "geoemb: %s %dd model=%s dtype=%s"
18831883- ty (Conv.Geoemb.dimensions g) (Conv.Geoemb.model g) (Conv.Geoemb.data_type g);
18841884- Option.iter (pf ppf " gsd=%.4g") (Conv.Geoemb.gsd g);
18851885- Option.iter (pf ppf " layout=%s") (Conv.Geoemb.spatial_layout g);
18861886- Option.iter (pf ppf " build=%s") (Conv.Geoemb.build_version g);
18871887- (match Conv.Geoemb.chip_layout g with
21772177+ | Some g -> (
21782178+ let ty =
21792179+ match Conv.Geoemb.type_ g with `Pixel -> "pixel" | `Chip -> "chip"
21802180+ in
21812181+ nl ();
21822182+ pf ppf "geoemb: %s %dd model=%s dtype=%s" ty (Conv.Geoemb.dimensions g)
21832183+ (Conv.Geoemb.model g) (Conv.Geoemb.data_type g);
21842184+ Option.iter (pf ppf " gsd=%.4g") (Conv.Geoemb.gsd g);
21852185+ Option.iter (pf ppf " layout=%s") (Conv.Geoemb.spatial_layout g);
21862186+ Option.iter (pf ppf " build=%s") (Conv.Geoemb.build_version g);
21872187+ (match Conv.Geoemb.chip_layout g with
18882188 | Some cl ->
18891889- let lt = match Conv.Geoemb.Chip_layout.layout_type cl with
18901890- | `Regular_grid -> "regular_grid" | `Irregular -> "irregular" in
18911891- let (h, w) = Conv.Geoemb.Chip_layout.chip_size cl in
18921892- nl (); pf ppf " chip: %s %dx%d" lt h w;
18931893- Option.iter (fun (sy, sx) -> pf ppf " stride=%dx%d" sy sx)
18941894- (Conv.Geoemb.Chip_layout.stride cl)
21892189+ let lt =
21902190+ match Conv.Geoemb.Chip_layout.layout_type cl with
21912191+ | `Regular_grid -> "regular_grid"
21922192+ | `Irregular -> "irregular"
21932193+ in
21942194+ let h, w = Conv.Geoemb.Chip_layout.chip_size cl in
21952195+ nl ();
21962196+ pf ppf " chip: %s %dx%d" lt h w;
21972197+ Option.iter
21982198+ (fun (sy, sx) -> pf ppf " stride=%dx%d" sy sx)
21992199+ (Conv.Geoemb.Chip_layout.stride cl)
18952200 | None -> ());
18961896- (match Conv.Geoemb.quantization g with
18971897- | Some q ->
18981898- nl (); pf ppf " quantization: %s %s" (Conv.Geoemb.Quantization.meth q)
18991899- (Conv.Geoemb.Quantization.original_dtype q);
19001900- Option.iter (pf ppf " -> %s") (Conv.Geoemb.Quantization.quantized_dtype q);
19011901- (match Conv.Geoemb.Quantization.scale q with
19021902- | Some (`Scalar s) ->
19031903- pf ppf " scale=%g" (Conv.Geoemb.Scale.Scalar.scale s);
19041904- if Conv.Geoemb.Scale.Scalar.offset s <> 0.0 then
19051905- pf ppf " offset=%g" (Conv.Geoemb.Scale.Scalar.offset s)
19061906- | Some (`Array a) ->
19071907- pf ppf " scale_array=%s" (Conv.Geoemb.Scale.Array_.array_name a);
19081908- Option.iter (pf ppf " nodata=%s") (Conv.Geoemb.Scale.Array_.nodata a)
19091909- | None -> ())
22012201+ match Conv.Geoemb.quantization g with
22022202+ | Some q -> (
22032203+ nl ();
22042204+ pf ppf " quantization: %s %s"
22052205+ (Conv.Geoemb.Quantization.meth q)
22062206+ (Conv.Geoemb.Quantization.original_dtype q);
22072207+ Option.iter (pf ppf " -> %s")
22082208+ (Conv.Geoemb.Quantization.quantized_dtype q);
22092209+ match Conv.Geoemb.Quantization.scale q with
22102210+ | Some (`Scalar s) ->
22112211+ pf ppf " scale=%g" (Conv.Geoemb.Scale.Scalar.scale s);
22122212+ if Conv.Geoemb.Scale.Scalar.offset s <> 0.0 then
22132213+ pf ppf " offset=%g" (Conv.Geoemb.Scale.Scalar.offset s)
22142214+ | Some (`Array a) ->
22152215+ pf ppf " scale_array=%s" (Conv.Geoemb.Scale.Array_.array_name a);
22162216+ Option.iter (pf ppf " nodata=%s")
22172217+ (Conv.Geoemb.Scale.Array_.nodata a)
22182218+ | None -> ())
19102219 | None -> ())
19111911- | None -> ());
19121912- (match Attrs.unknown attrs with
19131913- | Jsont.Object (mems, _) ->
19141914- List.iter (fun ((k, _), v) ->
19151915- let vs = match Jsont_bytesrw.encode_string ~format:Jsont.Minify Jsont.json v with
19161916- | Ok s when String.length s > 60 -> String.sub s 0 57 ^ "..."
19171917- | Ok s -> s | Error _ -> "?"
19181918- in
19191919- nl (); pf ppf "%s: %s" k vs
19201920- ) mems
19211921- | _ -> ())
22202220+ | None -> ());
22212221+ match Attrs.unknown attrs with
22222222+ | Jsont.Object (mems, _) ->
22232223+ List.iter
22242224+ (fun ((k, _), v) ->
22252225+ let vs =
22262226+ match
22272227+ Jsont_bytesrw.encode_string ~format:Jsont.Minify Jsont.json v
22282228+ with
22292229+ | Ok s when String.length s > 60 -> String.sub s 0 57 ^ "..."
22302230+ | Ok s -> s
22312231+ | Error _ -> "?"
22322232+ in
22332233+ nl ();
22342234+ pf ppf "%s: %s" k vs)
22352235+ mems
22362236+ | _ -> ()
1922223719232238let pp_attrs ppf attrs = pp_indented_attrs " " ppf attrs
1924223919252240let pp_probe_result ppf result =
19262241 pf ppf "[%a]" pp_node_kind result.node;
19271927- let attrs = match result.attrs with
19281928- | Some a -> a | None -> node_attrs result.node
22422242+ let attrs =
22432243+ match result.attrs with Some a -> a | None -> node_attrs result.node
19292244 in
19302245 pp_indented_attrs " " ppf attrs;
19311931- if result.children <> [] then
19321932- pp_tree " " ppf result.children;
22462246+ if result.children <> [] then pp_tree " " ppf result.children;
19332247 pf ppf "\n"
+307-316
src/zarr_jsont.mli
···11(** Type-safe bidirectional JSON codecs for
22- {{:https://zarr-specs.readthedocs.io/en/latest/}Zarr} v2 and v3
33- array and group metadata.
22+ {{:https://zarr-specs.readthedocs.io/en/latest/}Zarr} v2 and v3 array and
33+ group metadata.
4455- This library provides {!Jsont.t} codecs for decoding and encoding the
66- JSON metadata used by
77- {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html}Zarr v2}
88- and {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html}Zarr v3}
99- stores. It also includes best-effort codecs for several
1010- {{:https://github.com/zarr-conventions}zarr conventions}: geo-proj,
1111- spatial, multiscales, and geoembeddings.
55+ This library provides {!Jsont.t} codecs for decoding and encoding the JSON
66+ metadata used by
77+ {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html}Zarr v2} and
88+ {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html}Zarr v3}
99+ stores. It also includes best-effort codecs for several
1010+ {{:https://github.com/zarr-conventions}zarr conventions}: geo-proj, spatial,
1111+ multiscales, and geoembeddings.
12121313- All types use polymorphic variants. Known extensions and codecs are
1414- enumerated with an [`Other] escape hatch for unrecognised values.
1515- Unknown JSON fields are preserved throughout via
1616- {!Jsont.Object.keep_unknown} so that round-tripping is faithful.
1313+ All types use polymorphic variants. Known extensions and codecs are
1414+ enumerated with an [`Other] escape hatch for unrecognised values. Unknown
1515+ JSON fields are preserved throughout via {!Jsont.Object.keep_unknown} so
1616+ that round-tripping is faithful.
17171818 {2 Quick start}
1919···41414242 Types used by both Zarr v2 and v3 metadata. *)
43434444+type fill_value =
4545+ [ `Null
4646+ | `Bool of bool
4747+ | `Int of int64
4848+ | `Float of float
4949+ | `Complex of float * float
5050+ | `Bytes of string ]
4451(** The value stored in uninitialized or missing chunks.
45524653 In JSON, fill values appear as multiple sorts:
···54615562 See
5663 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#fill-value}v3
5757- fill value} and
6464+ fill value} and
5865 {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html#fill-value}v2
5959- fill value}. *)
6060-type fill_value = [
6161- | `Null
6262- | `Bool of bool
6363- | `Int of int64
6464- | `Float of float
6565- | `Complex of float * float
6666- | `Bytes of string
6767-]
6666+ fill value}. *)
68676968val fill_value_jsont : fill_value Jsont.t
7070-(** Codec for {!fill_value}. Dispatches on the JSON sort via
7171- {!Jsont.any}: null, boolean, number, string, and array are each
7272- routed to a specialised sub-codec. *)
6969+(** Codec for {!fill_value}. Dispatches on the JSON sort via {!Jsont.any}: null,
7070+ boolean, number, string, and array are each routed to a specialised
7171+ sub-codec. *)
73727373+type endian = [ `Little | `Big | `Not_applicable ]
7474(** Byte order indicator from a NumPy dtype typestr.
7575 - [`Little] — ['<'] little-endian
7676 - [`Big] — ['>'] big-endian
7777 - [`Not_applicable] — ['|'] or ['='], used for single-byte types *)
7878-type endian = [ `Little | `Big | `Not_applicable ]
79787979+type dtype =
8080+ [ `Bool
8181+ | `Int of endian * int (** Signed integer; size in bytes. *)
8282+ | `Uint of endian * int (** Unsigned integer; size in bytes. *)
8383+ | `Float of endian * int (** IEEE float; size in bytes. *)
8484+ | `Complex of endian * int (** Complex float pair; total size in bytes. *)
8585+ | `Timedelta of endian * string (** Time delta; unit string (e.g. ["s"]). *)
8686+ | `Datetime of endian * string (** Datetime; unit string (e.g. ["ns"]). *)
8787+ | `String of int (** Fixed-length byte string; size in bytes. *)
8888+ | `Unicode of endian * int (** Fixed-length unicode; number of characters. *)
8989+ | `Raw of int (** Void / raw bytes; size in bytes. *)
9090+ | `Structured of (string * dtype * int list option) list
9191+ (** Compound type: list of [(field_name, field_dtype, optional_shape)]. *)
9292+ ]
8093(** NumPy array dtype as used in Zarr v2
8194 {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html#data-type-encoding}
8282- array metadata}.
9595+ array metadata}.
83968497 Simple types are encoded as JSON strings in
8598 {{:https://numpy.org/doc/stable/reference/arrays.interface.html#arrays-interface}
8686- NumPy typestr} format: a one-character byte-order indicator (['<'],
8787- ['>'], or ['|']), a one-character type code, and a size in bytes.
8888- For example:
9999+ NumPy typestr} format: a one-character byte-order indicator (['<'], ['>'],
100100+ or ['|']), a one-character type code, and a size in bytes. For example:
89101 - ["<f8"] — little-endian 64-bit float
90102 - ["|b1"] — boolean
91103 - ["<M8[ns]"] — little-endian datetime with nanosecond units
921049393- Structured (compound) types are encoded as JSON arrays of field
9494- descriptors: [[\["name","<f4"\], \["name","<i2",\[3\]\]]]. Each
9595- field has a name, a dtype (which may itself be structured), and an
9696- optional shape. *)
9797-type dtype = [
9898- | `Bool
9999- | `Int of endian * int (** Signed integer; size in bytes. *)
100100- | `Uint of endian * int (** Unsigned integer; size in bytes. *)
101101- | `Float of endian * int (** IEEE float; size in bytes. *)
102102- | `Complex of endian * int (** Complex float pair; total size in bytes. *)
103103- | `Timedelta of endian * string (** Time delta; unit string (e.g. ["s"]). *)
104104- | `Datetime of endian * string (** Datetime; unit string (e.g. ["ns"]). *)
105105- | `String of int (** Fixed-length byte string; size in bytes. *)
106106- | `Unicode of endian * int (** Fixed-length unicode; number of characters. *)
107107- | `Raw of int (** Void / raw bytes; size in bytes. *)
108108- | `Structured of (string * dtype * int list option) list
109109- (** Compound type: list of [(field_name, field_dtype, optional_shape)]. *)
110110-]
105105+ Structured (compound) types are encoded as JSON arrays of field descriptors:
106106+ [[["name","<f4"], ["name","<i2",[3]]]]. Each field has a name, a dtype
107107+ (which may itself be structured), and an optional shape. *)
111108112109val dtype_jsont : dtype Jsont.t
113113-(** Codec for {!dtype}. Simple types round-trip through JSON strings;
114114- structured types round-trip through JSON arrays. The codec is
115115- recursive: structured field dtypes may themselves be structured. *)
110110+(** Codec for {!dtype}. Simple types round-trip through JSON strings; structured
111111+ types round-trip through JSON arrays. The codec is recursive: structured
112112+ field dtypes may themselves be structured. *)
116113117114(** {1:escape Escape-hatch types}
118115119119- Catch-all types for unrecognised codecs and extensions, ensuring
120120- that unknown values are preserved and round-tripped faithfully. *)
116116+ Catch-all types for unrecognised codecs and extensions, ensuring that
117117+ unknown values are preserved and round-tripped faithfully. *)
121118122119(** Unrecognised Zarr v2 codec (compressor or filter).
123120124124- V2 codecs are JSON objects with an ["id"] key naming the codec and
125125- arbitrary additional configuration fields. For example:
126126- {[{"id": "custom_codec", "param1": 42, "param2": "hello"}]}
121121+ V2 codecs are JSON objects with an ["id"] key naming the codec and arbitrary
122122+ additional configuration fields. For example:
123123+ {[
124124+ {"id": "custom_codec", "param1": 42, "param2": "hello"}
125125+ ]}
127126128128- Unknown fields are captured via {!Jsont.Object.keep_unknown} and
129129- preserved on re-encoding. *)
127127+ Unknown fields are captured via {!Jsont.Object.keep_unknown} and preserved
128128+ on re-encoding. *)
130129module Other_codec : sig
131130 type t
132131···142141143142(** Unrecognised Zarr v3 extension point.
144143145145- V3 uses a uniform extension format for data types, chunk grids, chunk
146146- key encodings, codecs, and storage transformers. Each is a JSON
147147- object with:
144144+ V3 uses a uniform extension format for data types, chunk grids, chunk key
145145+ encodings, codecs, and storage transformers. Each is a JSON object with:
148146 - ["name"] — extension identifier
149147 - ["configuration"] — optional configuration object
150148 - ["must_understand"] — boolean (default [true]); if [false],
···152150153151 See
154152 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#extension-points}
155155- v3 extension points}. *)
153153+ v3 extension points}. *)
156154module Other_ext : sig
157155 type t
158156···163161 (** The extension configuration, if any. *)
164162165163 val must_understand : t -> bool
166166- (** Whether implementations must understand this extension. Defaults
167167- to [true] when absent in JSON; omitted on encode when [true]. *)
164164+ (** Whether implementations must understand this extension. Defaults to [true]
165165+ when absent in JSON; omitted on encode when [true]. *)
168166169167 val make : string -> Jsont.json option -> bool -> t
170168 val jsont : t Jsont.t
···173171(** {1:v3 Zarr v3}
174172175173 Types and codecs for
176176- {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html}
177177- Zarr v3} metadata. V3 stores a single [zarr.json] file per node
178178- (array or group), with the ["node_type"] field distinguishing the
179179- two. *)
174174+ {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html} Zarr v3}
175175+ metadata. V3 stores a single [zarr.json] file per node (array or group),
176176+ with the ["node_type"] field distinguishing the two. *)
180177module V3 : sig
181181-182178 (** {2 Codecs}
183179184180 A v3 array's data is processed through a
185181 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#codecs}
186186- codec chain}: zero or more array-to-array codecs, then exactly one
187187- array-to-bytes codec, then zero or more bytes-to-bytes codecs.
188188- Each codec is a JSON object with ["name"] and optional
189189- ["configuration"]. *)
182182+ codec chain}: zero or more array-to-array codecs, then exactly one
183183+ array-to-bytes codec, then zero or more bytes-to-bytes codecs. Each codec
184184+ is a JSON object with ["name"] and optional ["configuration"]. *)
190185 module Codec : sig
191191-192186 (** The
193187 {{:https://zarr-specs.readthedocs.io/en/latest/v3/codecs/bytes/index.html}
194194- bytes} codec (array-to-bytes). Serialises array elements in
195195- lexicographic (C) order. The [endian] field specifies byte order;
196196- it is omitted for single-byte data types. *)
188188+ bytes} codec (array-to-bytes). Serialises array elements in
189189+ lexicographic (C) order. The [endian] field specifies byte order; it is
190190+ omitted for single-byte data types. *)
197191 module Bytes : sig
198192 type t
193193+199194 val endian : t -> [ `Little | `Big ] option
200200- (** [None] when endian is not applicable (single-byte data types
201201- such as [bool] or [uint8]). *)
195195+ (** [None] when endian is not applicable (single-byte data types such as
196196+ [bool] or [uint8]). *)
202197 end
203198204199 (** The
205200 {{:https://zarr-specs.readthedocs.io/en/latest/v3/codecs/gzip/index.html}
206206- gzip} codec (bytes-to-bytes). Compresses data using the gzip
207207- algorithm. *)
201201+ gzip} codec (bytes-to-bytes). Compresses data using the gzip algorithm.
202202+ *)
208203 module Gzip : sig
209204 type t
205205+210206 val level : t -> int
211207 (** Compression level, 0 (no compression) to 9 (best). *)
212208 end
213209214210 (** The
215211 {{:https://zarr-specs.readthedocs.io/en/latest/v3/codecs/blosc/index.html}
216216- blosc} codec (bytes-to-bytes). Meta-compressor that delegates
217217- to one of several compression libraries. *)
212212+ blosc} codec (bytes-to-bytes). Meta-compressor that delegates to one of
213213+ several compression libraries. *)
218214 module Blosc : sig
219215 type t
216216+220217 val cname : t -> string
221218 (** Compressor name: ["lz4"], ["lz4hc"], ["blosclz"], ["zstd"],
222219 ["snappy"], or ["zlib"]. *)
···228225 (** Shuffle mode applied before compression. *)
229226230227 val typesize : t -> int option
231231- (** Element size in bytes for shuffling. [None] when shuffle is
228228+ (** Element size in bytes for shuffling. [None] when shuffle is
232229 [`Noshuffle]. *)
233230234231 val blocksize : t -> int
···237234238235 (** The
239236 {{:https://zarr-specs.readthedocs.io/en/latest/v3/codecs/transpose/index.html}
240240- transpose} codec (array-to-array). Permutes array dimensions. *)
237237+ transpose} codec (array-to-array). Permutes array dimensions. *)
241238 module Transpose : sig
242239 type t
240240+243241 val order : t -> int list
244244- (** Dimension permutation, e.g. [\[1; 0; 2\]]. *)
242242+ (** Dimension permutation, e.g. [[1; 0; 2]]. *)
245243 end
246244247245 (** The
248246 {{:https://zarr-specs.readthedocs.io/en/latest/v3/codecs/sharding-indexed/index.html}
249249- sharding} codec (array-to-bytes). Bundles multiple inner chunks
250250- into a single shard with an embedded index for random access.
251251- The codec is recursive: inner chunks have their own codec chain. *)
247247+ sharding} codec (array-to-bytes). Bundles multiple inner chunks into a
248248+ single shard with an embedded index for random access. The codec is
249249+ recursive: inner chunks have their own codec chain. *)
252250 module Sharding : sig
253251 type t
254254- and codec = [
255255- | `Bytes of Bytes.t
252252+253253+ and codec =
254254+ [ `Bytes of Bytes.t
256255 | `Gzip of Gzip.t
257256 | `Blosc of Blosc.t
258257 | `Crc32c
259258 | `Transpose of Transpose.t
260259 | `Sharding of t
261261- | `Other of Other_ext.t
262262- ]
260260+ | `Other of Other_ext.t ]
261261+263262 val chunk_shape : t -> int list
264263 (** Shape of inner chunks within each shard. *)
265264···267266 (** Codec chain applied to each inner chunk. *)
268267269268 val index_codecs : t -> codec list
270270- (** Codec chain for the shard index. Empty list if unspecified. *)
269269+ (** Codec chain for the shard index. Empty list if unspecified. *)
271270272271 val index_location : t -> [ `Start | `End ]
273273- (** Where the shard index is stored. Default [`End]. *)
272272+ (** Where the shard index is stored. Default [`End]. *)
274273 end
275274 end
276275277277- (** A v3 codec pipeline entry. The core specification defines six
278278- codecs; unrecognised codecs decode as [`Other].
276276+ type codec = Codec.Sharding.codec
277277+ (** A v3 codec pipeline entry. The core specification defines six codecs;
278278+ unrecognised codecs decode as [`Other].
279279280280 - [`Bytes] — array-to-bytes serialisation
281281 - [`Gzip] — gzip compression
···283283 - [`Crc32c] — CRC-32C checksum (no configuration)
284284 - [`Transpose] — dimension permutation
285285 - [`Sharding] — sharding with inner chunks *)
286286- type codec = Codec.Sharding.codec
287286288287 val codec_jsont : codec Jsont.t
289289- (** Codec for {!codec}. Dispatches on the ["name"] field.
290290- Sharding codecs are decoded recursively so that inner codec
291291- chains are fully typed. *)
288288+ (** Codec for {!codec}. Dispatches on the ["name"] field. Sharding codecs are
289289+ decoded recursively so that inner codec chains are fully typed. *)
292290293291 (** V3
294292 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#data-type}
295295- data type}. Core types are encoded as JSON strings; extension
296296- types as JSON objects with ["name"] and ["configuration"].
293293+ data type}. Core types are encoded as JSON strings; extension types as
294294+ JSON objects with ["name"] and ["configuration"].
297295298296 The fifteen core types are:
299297 - Booleans: [bool]
···304302305303 Raw bit types ([r8], [r16], etc.) use the ["r<bits>"] pattern. *)
306304 module Data_type : sig
307307- type t = [
308308- | `Bool | `Int8 | `Int16 | `Int32 | `Int64
309309- | `Uint8 | `Uint16 | `Uint32 | `Uint64
310310- | `Float16 | `Float32 | `Float64
311311- | `Complex64 | `Complex128
312312- | `Raw of int (** Raw bits; the integer is the bit width. *)
313313- | `Other of Other_ext.t (** Extension data type. *)
314314- ]
305305+ type t =
306306+ [ `Bool
307307+ | `Int8
308308+ | `Int16
309309+ | `Int32
310310+ | `Int64
311311+ | `Uint8
312312+ | `Uint16
313313+ | `Uint32
314314+ | `Uint64
315315+ | `Float16
316316+ | `Float32
317317+ | `Float64
318318+ | `Complex64
319319+ | `Complex128
320320+ | `Raw of int (** Raw bits; the integer is the bit width. *)
321321+ | `Other of Other_ext.t (** Extension data type. *) ]
315322 end
316323317324 val data_type_jsont : Data_type.t Jsont.t
318318- (** Codec for {!Data_type.t}. Core types decode from JSON strings;
319319- extension types from JSON objects. The ["r<bits>"] pattern
320320- decodes as [`Raw bits]. *)
325325+ (** Codec for {!Data_type.t}. Core types decode from JSON strings; extension
326326+ types from JSON objects. The ["r<bits>"] pattern decodes as [`Raw bits].
327327+ *)
321328322329 (** V3
323330 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-grid}
324324- chunk grid}. Defines how the array is divided into chunks.
325325- The only core grid is ["regular"] (fixed-shape chunks). *)
331331+ chunk grid}. Defines how the array is divided into chunks. The only core
332332+ grid is ["regular"] (fixed-shape chunks). *)
326333 module Chunk_grid : sig
327334 (** Regular chunk grid: every chunk has the same shape. *)
328335 module Regular : sig
329336 type t
337337+330338 val chunk_shape : t -> int list
331331- (** Dimensions of each chunk, e.g. [\[1000; 100\]]. *)
339339+ (** Dimensions of each chunk, e.g. [[1000; 100]]. *)
332340 end
333341334342 type t = [ `Regular of Regular.t | `Other of Other_ext.t ]
335343 end
336344337345 val chunk_grid_jsont : Chunk_grid.t Jsont.t
338338- (** Codec for {!Chunk_grid.t}. Dispatches on the ["name"] field. *)
346346+ (** Codec for {!Chunk_grid.t}. Dispatches on the ["name"] field. *)
339347340348 (** V3
341349 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-key-encoding}
342342- chunk key encoding}. Maps chunk grid coordinates to store keys.
343343- The only core encoding is ["default"]. *)
350350+ chunk key encoding}. Maps chunk grid coordinates to store keys. The only
351351+ core encoding is ["default"]. *)
344352 module Chunk_key_encoding : sig
345345- (** Default key encoding. Chunk at grid position [(1, 2, 3)] is
346346- stored at key ["c/1/2/3"] (with ["/"]) or ["c.1.2.3"] (with
347347- ["."]). The prefix ["c"] distinguishes chunk keys from
348348- metadata keys. *)
353353+ (** Default key encoding. Chunk at grid position [(1, 2, 3)] is stored at
354354+ key ["c/1/2/3"] (with ["/"]) or ["c.1.2.3"] (with ["."]). The prefix
355355+ ["c"] distinguishes chunk keys from metadata keys. *)
349356 module Default : sig
350357 type t
358358+351359 val separator : t -> [ `Slash | `Dot ]
352352- (** The separator between coordinate components.
353353- Default is [`Slash]. *)
360360+ (** The separator between coordinate components. Default is [`Slash]. *)
354361 end
355362356363 type t = [ `Default of Default.t | `Other of Other_ext.t ]
357364 end
358365359366 val chunk_key_encoding_jsont : Chunk_key_encoding.t Jsont.t
360360- (** Codec for {!Chunk_key_encoding.t}. Dispatches on the ["name"]
361361- field. *)
367367+ (** Codec for {!Chunk_key_encoding.t}. Dispatches on the ["name"] field. *)
362368363369 (** Complete v3
364370 {{:https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#array-metadata}
365365- array metadata} as stored in [zarr.json].
371371+ array metadata} as stored in [zarr.json].
366372367367- Required fields: [shape], [data_type], [chunk_grid],
368368- [chunk_key_encoding], [codecs], [fill_value].
373373+ Required fields: [shape], [data_type], [chunk_grid], [chunk_key_encoding],
374374+ [codecs], [fill_value].
369375370370- Optional fields: [dimension_names] (named dimensions, with [null]
371371- entries for unnamed ones), [storage_transformers], [attributes]. *)
376376+ Optional fields: [dimension_names] (named dimensions, with [null] entries
377377+ for unnamed ones), [storage_transformers], [attributes]. *)
372378 module Array_meta : sig
373379 type t
374380375381 val shape : t -> int list
376376- (** Array dimensions, e.g. [\[10000; 1000\]]. *)
382382+ (** Array dimensions, e.g. [[10000; 1000]]. *)
377383378384 val data_type : t -> Data_type.t
379385 (** Element data type. *)
···391397 (** Default value for uninitialised chunks. *)
392398393399 val dimension_names : t -> string option list option
394394- (** Named dimensions. [None] if absent; [Some \[Some "x"; None\]]
395395- if partially named. *)
400400+ (** Named dimensions. [None] if absent; [Some [Some "x"; None]] if partially
401401+ named. *)
396402397403 val storage_transformers : t -> Other_ext.t list option
398404 (** Optional storage transformer extensions. *)
···402408 end
403409404410 val array_meta_jsont : Array_meta.t Jsont.t
405405- (** Codec for {!Array_meta.t}. Consumes ["zarr_format"] and
406406- ["node_type"] on decode (always writes [3] / ["array"] on encode).
407407- The ["attributes"] sub-object is consumed but decoded separately
408408- at the {!V3_node} level. *)
411411+ (** Codec for {!Array_meta.t}. Consumes ["zarr_format"] and ["node_type"] on
412412+ decode (always writes [3] / ["array"] on encode). The ["attributes"]
413413+ sub-object is consumed but decoded separately at the {!V3_node} level. *)
409414end
410415411416(** {1:v2 Zarr v2}
412417413418 Types and codecs for
414419 {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html}Zarr v2}
415415- metadata. V2 uses three separate files: [.zarray] (array metadata),
416416- [.zgroup] (group metadata, just [\{"zarr_format": 2\}]), and
417417- [.zattrs] (user attributes). *)
420420+ metadata. V2 uses three separate files: [.zarray] (array metadata),
421421+ [.zgroup] (group metadata, just [\{"zarr_format": 2\}]), and [.zattrs] (user
422422+ attributes). *)
418423module V2 : sig
419419-420424 (** {2 Compressors}
421425422422- V2 compressors appear in the ["compressor"] field of [.zarray].
423423- Each is a JSON object with an ["id"] field naming the compressor
424424- and codec-specific configuration. A [null] value means no
425425- compression. *)
426426+ V2 compressors appear in the ["compressor"] field of [.zarray]. Each is a
427427+ JSON object with an ["id"] field naming the compressor and codec-specific
428428+ configuration. A [null] value means no compression. *)
426429 module Compressor : sig
427427-428430 (** {{:https://www.blosc.org/}Blosc} meta-compressor. *)
429431 module Blosc : sig
430432 type t
433433+431434 val cname : t -> string
432435 (** Compression library name (e.g. ["lz4"], ["zstd"]). *)
433436···447450 (** {{:https://zlib.net/}Zlib} compressor. *)
448451 module Zlib : sig
449452 type t
453453+450454 val level : t -> int
451455 (** Compression level, 1–9. *)
452456···454458 end
455459 end
456460457457- (** A v2 compressor. Known compressors are decoded into typed
458458- variants; unrecognised ones are captured as {!Other_codec.t}. *)
459459- type compressor = [
460460- | `Blosc of Compressor.Blosc.t
461461+ type compressor =
462462+ [ `Blosc of Compressor.Blosc.t
461463 | `Zlib of Compressor.Zlib.t
462462- | `Other of Other_codec.t
463463- ]
464464+ | `Other of Other_codec.t ]
465465+ (** A v2 compressor. Known compressors are decoded into typed variants;
466466+ unrecognised ones are captured as {!Other_codec.t}. *)
464467465468 val compressor_jsont : compressor Jsont.t
466466- (** Codec for {!compressor}. Dispatches on the ["id"] field. *)
469469+ (** Codec for {!compressor}. Dispatches on the ["id"] field. *)
467470468471 (** {2 Filters}
469472470470- V2 filters appear in the ["filters"] field of [.zarray] as a
471471- JSON array of objects (or [null] for no filters). Each object
472472- has an ["id"] field. *)
473473+ V2 filters appear in the ["filters"] field of [.zarray] as a JSON array of
474474+ objects (or [null] for no filters). Each object has an ["id"] field. *)
473475 module Filter : sig
474474-475476 (** Delta filter: stores differences between consecutive elements. *)
476477 module Delta : sig
477478 type t
479479+478480 val dtype : t -> string
479481 (** Data type of the input, as a NumPy typestr (e.g. ["<f8"]). *)
480482···485487 end
486488 end
487489490490+ type filter = [ `Delta of Filter.Delta.t | `Other of Other_codec.t ]
488491 (** A v2 filter. *)
489489- type filter = [
490490- | `Delta of Filter.Delta.t
491491- | `Other of Other_codec.t
492492- ]
493492494493 val filter_jsont : filter Jsont.t
495495- (** Codec for {!filter}. Dispatches on the ["id"] field. *)
494494+ (** Codec for {!filter}. Dispatches on the ["id"] field. *)
496495497496 (** Complete v2
498497 {{:https://zarr-specs.readthedocs.io/en/latest/v2/core.html#metadata}
499499- array metadata} as stored in [.zarray]. *)
498498+ array metadata} as stored in [.zarray]. *)
500499 module Array_meta : sig
501500 type t
502501···504503 (** Array dimensions. *)
505504506505 val chunks : t -> int list
507507- (** Chunk dimensions. All chunks have the same shape. *)
506506+ (** Chunk dimensions. All chunks have the same shape. *)
508507509508 val dtype : t -> dtype
510509 (** Element data type in NumPy typestr format. *)
511510512511 val compressor : t -> compressor option
513513- (** Primary compressor. [None] means no compression. *)
512512+ (** Primary compressor. [None] means no compression. *)
514513515514 val fill_value : t -> fill_value
516515 (** Default value for uninitialised chunks. *)
517516518517 val order : t -> [ `C | `F ]
519519- (** Memory layout: [`C] for row-major (C order), [`F] for
520520- column-major (Fortran order). *)
518518+ (** Memory layout: [`C] for row-major (C order), [`F] for column-major
519519+ (Fortran order). *)
521520522521 val filters : t -> filter list option
523523- (** Pre-compression filter pipeline. [None] means no filters. *)
522522+ (** Pre-compression filter pipeline. [None] means no filters. *)
524523525524 val dimension_separator : t -> [ `Dot | `Slash ] option
526526- (** Separator used in chunk keys. [None] uses the default ["."]. *)
525525+ (** Separator used in chunk keys. [None] uses the default ["."]. *)
527526528527 val unknown : t -> Jsont.json
529528 (** Extra fields preserved for round-tripping. *)
530529 end
531530532531 val array_meta_jsont : Array_meta.t Jsont.t
533533- (** Codec for {!Array_meta.t}. Consumes ["zarr_format"] on decode
534534- (always writes [2] on encode). *)
532532+ (** Codec for {!Array_meta.t}. Consumes ["zarr_format"] on decode (always
533533+ writes [2] on encode). *)
535534end
536535537536(** {1:conv Conventions}
538537539539- {{:https://github.com/zarr-conventions}Zarr conventions} extend the
540540- base metadata with domain-specific attributes. Each convention uses
541541- a namespace prefix (e.g. ["proj:"], ["spatial:"]) and registers
542542- itself in the ["zarr_conventions"] array within the attributes
543543- object.
538538+ {{:https://github.com/zarr-conventions}Zarr conventions} extend the base
539539+ metadata with domain-specific attributes. Each convention uses a namespace
540540+ prefix (e.g. ["proj:"], ["spatial:"]) and registers itself in the
541541+ ["zarr_conventions"] array within the attributes object.
544542545545- This library provides typed codecs for four conventions. Each
546546- sub-module exposes a {!Conv.Meta.t} constant for registration and a
547547- [jsont] codec that decodes from the flat attributes object (using
548548- {!Jsont.Object.skip_unknown} to coexist with other conventions). *)
543543+ This library provides typed codecs for four conventions. Each sub-module
544544+ exposes a {!Conv.Meta.t} constant for registration and a [jsont] codec that
545545+ decodes from the flat attributes object (using {!Jsont.Object.skip_unknown}
546546+ to coexist with other conventions). *)
549547module Conv : sig
550550-551551- (** Convention registration metadata, as stored in the
552552- ["zarr_conventions"] array. At least one of [uuid], [schema_url],
553553- or [spec_url] should be present for identification. *)
548548+ (** Convention registration metadata, as stored in the ["zarr_conventions"]
549549+ array. At least one of [uuid], [schema_url], or [spec_url] should be
550550+ present for identification. *)
554551 module Meta : sig
555552 type t
553553+556554 val uuid : t -> string
557555 (** Permanent identifier for the convention. *)
558556···574572 (** {{:https://github.com/zarr-experimental/geo-proj}Geo-projection}
575573 convention ([proj:] prefix).
576574577577- Defines coordinate reference system (CRS) metadata for geospatial
578578- data. At least one of [code], [wkt2], or [projjson] should be
579579- present.
575575+ Defines coordinate reference system (CRS) metadata for geospatial data. At
576576+ least one of [code], [wkt2], or [projjson] should be present.
580577581578 - [proj:code] — authority:code identifier (e.g. ["EPSG:4326"])
582579 - [proj:wkt2] — WKT2 (ISO 19162:2019) CRS string
583580 - [proj:projjson] — PROJJSON CRS object *)
584581 module Proj : sig
585582 type t
583583+586584 val code : t -> string option
587585 (** Authority:code CRS identifier, e.g. ["EPSG:4326"]. *)
588586···602600 (** {{:https://github.com/zarr-conventions/spatial}Spatial} convention
603601 ([spatial:] prefix).
604602605605- Describes the mapping between array indices and spatial
606606- coordinates. Works for both geospatial and non-geospatial data
607607- (microscopy, medical imaging, etc.).
603603+ Describes the mapping between array indices and spatial coordinates. Works
604604+ for both geospatial and non-geospatial data (microscopy, medical imaging,
605605+ etc.).
608606609607 The affine transform maps pixel coordinates [(i, j)] to spatial
610608 coordinates [(x, y)] via:
611609 {[
612612- x = a*i + b*j + c
613613- y = d*i + e*j + f
610610+ x = (a * i) + (b * j) + c y = (d * i) + (e * j) + f
614611 ]}
615612 where the six coefficients are stored in [transform] as
616616- [\[a; b; c; d; e; f\]]. *)
613613+ [[a; b; c; d; e; f]]. *)
617614 module Spatial : sig
618615 type t
616616+619617 val dimensions : t -> string list
620618 (** Names of the spatial dimensions (e.g. [["y"; "x"]]). *)
621619622620 val bbox : t -> float list option
623623- (** Bounding box: [\[xmin; ymin; xmax; ymax\]] for 2D,
624624- [\[xmin; ymin; zmin; xmax; ymax; zmax\]] for 3D. *)
621621+ (** Bounding box: [[xmin; ymin; xmax; ymax]] for 2D,
622622+ [[xmin; ymin; zmin; xmax; ymax; zmax]] for 3D. *)
625623626624 val transform_type : t -> string option
627627- (** Type of coordinate transform. Currently only ["affine"] is
628628- defined; defaults to ["affine"] when absent. *)
625625+ (** Type of coordinate transform. Currently only ["affine"] is defined;
626626+ defaults to ["affine"] when absent. *)
629627630628 val transform : t -> float list option
631631- (** Affine coefficients [\[a; b; c; d; e; f\]] for 2D. *)
629629+ (** Affine coefficients [[a; b; c; d; e; f]] for 2D. *)
632630633631 val shape : t -> int list option
634634- (** Shape of the spatial dimensions [\[height; width\]]. Useful
635635- when the spatial shape differs from the full array shape. *)
632632+ (** Shape of the spatial dimensions [[height; width]]. Useful when the
633633+ spatial shape differs from the full array shape. *)
636634637635 val registration : t -> [ `Pixel | `Node ] option
638638- (** Grid cell registration. [`Pixel] (default) means cell
639639- boundaries align with coordinate values; [`Node] means cell
640640- centres align with coordinate values. *)
636636+ (** Grid cell registration. [`Pixel] (default) means cell boundaries align
637637+ with coordinate values; [`Node] means cell centres align with coordinate
638638+ values. *)
641639642640 val meta : Meta.t
643641 (** Convention registration metadata (UUID
···647645 end
648646649647 (** {{:https://github.com/geo-embeddings/embeddings-zarr-convention}
650650- Geoembeddings} convention ([geoemb:] prefix).
648648+ Geoembeddings} convention ([geoemb:] prefix).
651649652652- Describes geospatial embedding groups with model provenance,
653653- processing parameters, and optional quantization metadata.
654654- Supports two embedding types:
650650+ Describes geospatial embedding groups with model provenance, processing
651651+ parameters, and optional quantization metadata. Supports two embedding
652652+ types:
655653656656- - {b Pixel embeddings}: per-pixel dense embeddings where each
657657- spatial location has an embedding vector.
658658- - {b Chip embeddings}: image patch embeddings where non-overlapping
659659- or overlapping regions are encoded into single vectors.
654654+ - {b Pixel embeddings}: per-pixel dense embeddings where each spatial
655655+ location has an embedding vector.
656656+ - {b Chip embeddings}: image patch embeddings where non-overlapping or
657657+ overlapping regions are encoded into single vectors.
660658661661- When [type_] is [`Chip], the [chip_layout] field is also
662662- required. *)
659659+ When [type_] is [`Chip], the [chip_layout] field is also required. *)
663660 module Geoemb : sig
664664-665665- (** Chip layout for chip-type embeddings, describing how source
666666- imagery was divided into patches. *)
661661+ (** Chip layout for chip-type embeddings, describing how source imagery was
662662+ divided into patches. *)
667663 module Chip_layout : sig
668664 type t
665665+669666 val layout_type : t -> [ `Regular_grid | `Irregular ]
670670- (** [`Regular_grid] for uniform non-overlapping or overlapping
671671- patches; [`Irregular] for variable-size patches. *)
667667+ (** [`Regular_grid] for uniform non-overlapping or overlapping patches;
668668+ [`Irregular] for variable-size patches. *)
672669673670 val chip_size : t -> int * int
674671 (** Chip dimensions [(height, width)] in pixels. *)
675672676673 val stride : t -> (int * int) option
677677- (** Stride [(y, x)] between chips. Defaults to [chip_size]
674674+ (** Stride [(y, x)] between chips. Defaults to [chip_size]
678675 (non-overlapping) when absent. *)
679676680677 val grid_id : t -> string option
···684681 (** URL to a grid definition document. *)
685682 end
686683687687- (** Scale parameters for dequantizing compressed embeddings. Uses
688688- a tagged union on the ["type"] field:
684684+ (** Scale parameters for dequantizing compressed embeddings. Uses a tagged
685685+ union on the ["type"] field:
689686690687 - {b Scalar}: [value = quantized * scale + offset]
691691- - {b Array}: [value\[..., y, x\] = quantized\[..., y, x\] *
692692- array\[..., y, x\]]; non-finite values in the scale array
693693- indicate no-data pixels. *)
688688+ - {b Array}:
689689+ [value[..., y, x] = quantized[..., y, x] * array[..., y, x]];
690690+ non-finite values in the scale array indicate no-data pixels. *)
694691 module Scale : sig
695692 (** Global scalar dequantization parameters. *)
696693 module Scalar : sig
697694 type t
695695+698696 val scale : t -> float
699697 (** Scale factor. *)
700698···705703 (** Per-pixel scale factors stored in a sibling zarr array. *)
706704 module Array_ : sig
707705 type t
706706+708707 val array_name : t -> string
709708 (** Name of the zarr array containing per-pixel scales. *)
710709711710 val nodata : t -> string option
712712- (** Value indicating no-data in the scale array (e.g.
713713- ["+inf"]). Represented as a string since the JSON value
714714- may be a number or a string. *)
711711+ (** Value indicating no-data in the scale array (e.g. ["+inf"]).
712712+ Represented as a string since the JSON value may be a number or a
713713+ string. *)
715714 end
716715717716 type t = [ `Scalar of Scalar.t | `Array of Array_.t ]
717717+718718 val jsont : t Jsont.t
719719 end
720720721721- (** Quantization details for embeddings compressed from their
722722- original floating-point representation. *)
721721+ (** Quantization details for embeddings compressed from their original
722722+ floating-point representation. *)
723723 module Quantization : sig
724724 type t
725725+725726 val meth : t -> string
726726- (** Quantization method (e.g. ["linear"],
727727- ["per_pixel_scale"], ["product_quantization"],
728728- ["binary"]). *)
727727+ (** Quantization method (e.g. ["linear"], ["per_pixel_scale"],
728728+ ["product_quantization"], ["binary"]). *)
729729730730 val original_dtype : t -> string
731731 (** Original data type before quantization (e.g. ["float32"]). *)
···741741 end
742742743743 type t
744744+744745 val type_ : t -> [ `Pixel | `Chip ]
745746 (** Embedding type. *)
746747···760761 (** Ground sample distance in metres. *)
761762762763 val chip_layout : t -> Chip_layout.t option
763763- (** Chip layout configuration. Required when [type_] is [`Chip]. *)
764764+ (** Chip layout configuration. Required when [type_] is [`Chip]. *)
764765765766 val quantization : t -> Quantization.t option
766767 (** Quantization details, if embeddings have been compressed. *)
767768768769 val spatial_layout : t -> string option
769769- (** Spatial organisation scheme: ["utm_zones"] (one group per UTM
770770- zone, named [utm01]–[utm60]) or ["global"]. *)
770770+ (** Spatial organisation scheme: ["utm_zones"] (one group per UTM zone,
771771+ named [utm01]–[utm60]) or ["global"]. *)
771772772773 val build_version : t -> string option
773774 (** Version of the software that built this store. *)
···785786 (** {{:https://github.com/zarr-conventions/multiscales}Multiscales}
786787 convention.
787788788788- Encodes multi-resolution pyramid metadata for hierarchical data
789789- stored in zarr groups. Each level in the pyramid is a separate
790790- zarr array (or group containing arrays), linked by relative
791791- coordinate transforms.
789789+ Encodes multi-resolution pyramid metadata for hierarchical data stored in
790790+ zarr groups. Each level in the pyramid is a separate zarr array (or group
791791+ containing arrays), linked by relative coordinate transforms.
792792793793- The [layout] array describes the pyramid levels. Each level has
794794- an [asset] path (relative to the group), an optional
795795- [derived_from] path, and a [transform] with [scale] and
796796- [translation] vectors describing the coordinate relationship to
797797- the source level. *)
793793+ The [layout] array describes the pyramid levels. Each level has an [asset]
794794+ path (relative to the group), an optional [derived_from] path, and a
795795+ [transform] with [scale] and [translation] vectors describing the
796796+ coordinate relationship to the source level. *)
798797 module Multiscales : sig
799799-800798 (** Relative coordinate transform between pyramid levels. *)
801799 module Transform : sig
802800 type t
801801+803802 val scale : t -> float list option
804804- (** Scale factors per axis. [> 1.0] = downsampling. *)
803803+ (** Scale factors per axis. [> 1.0] = downsampling. *)
805804806805 val translation : t -> float list option
807806 (** Translation offsets per axis in coordinate space. *)
···814813 (** A single pyramid level. *)
815814 module Layout_item : sig
816815 type t
816816+817817 val asset : t -> string
818818- (** Path to the zarr array or group for this level, relative to
819819- the parent group (e.g. ["0"], ["r10m"], ["0/data"]). *)
818818+ (** Path to the zarr array or group for this level, relative to the parent
819819+ group (e.g. ["0"], ["r10m"], ["0/data"]). *)
820820821821 val derived_from : t -> string option
822822 (** Path to the source level this one was derived from. *)
823823824824 val transform : t -> Transform.t option
825825- (** Coordinate transform relative to [derived_from]. Required
826826- when [derived_from] is present. *)
825825+ (** Coordinate transform relative to [derived_from]. Required when
826826+ [derived_from] is present. *)
827827828828 val resampling_method : t -> string option
829829- (** Resampling method used to derive this level (e.g.
830830- ["average"], ["nearest"], ["bilinear"]). Overrides the
831831- top-level default. *)
829829+ (** Resampling method used to derive this level (e.g. ["average"],
830830+ ["nearest"], ["bilinear"]). Overrides the top-level default. *)
832831833832 val unknown : t -> Jsont.json
834834- (** Additional fields (e.g. [spatial:shape],
835835- [spatial:transform]). *)
833833+ (** Additional fields (e.g. [spatial:shape], [spatial:transform]). *)
836834 end
837835838836 type t
837837+839838 val layout : t -> Layout_item.t list
840839 (** The pyramid levels, from highest to lowest resolution. *)
841840···853852(** {1:attrs Attributes}
854853855854 The composable attributes layer shared by all zarr node types.
856856- Convention-namespaced keys are routed to the appropriate convention
857857- codec; remaining keys are preserved in {!Attrs.unknown}. *)
855855+ Convention-namespaced keys are routed to the appropriate convention codec;
856856+ remaining keys are preserved in {!Attrs.unknown}. *)
858857module Attrs : sig
859858 type t
860859···883882val attrs_jsont : Attrs.t Jsont.t
884883(** Codec for {!Attrs.t}.
885884886886- On decode, routes convention-prefixed keys to sub-codecs. On
887887- encode, auto-populates ["zarr_conventions"] from whichever
888888- conventions are [Some], then merges their flat members alongside
889889- ["multiscales"] and unknown keys. *)
885885+ On decode, routes convention-prefixed keys to sub-codecs. On encode,
886886+ auto-populates ["zarr_conventions"] from whichever conventions are [Some],
887887+ then merges their flat members alongside ["multiscales"] and unknown keys.
888888+*)
890889891890(** {1:nodes Nodes}
892891893893- A zarr node is either an array or a group, with associated
894894- attributes. *)
892892+ A zarr node is either an array or a group, with associated attributes. *)
895893896894(** A Zarr v2 node. *)
897895module V2_node : sig
898896 type t
897897+899898 val kind : t -> [ `Array of V2.Array_meta.t | `Group ]
900899 (** [`Array] for [.zarray], [`Group] for [.zgroup]. *)
901900···908907(** A Zarr v3 node. *)
909908module V3_node : sig
910909 type t
910910+911911 val kind : t -> [ `Array of V3.Array_meta.t | `Group ]
912912 (** [`Array] if ["node_type"] is ["array"], [`Group] otherwise. *)
913913···918918end
919919920920val v2_array_jsont : V2_node.t Jsont.t
921921-(** Codec for a Zarr v2 [.zarray] file. Produces a {!V2_node.t} with
922922- [`Array] kind. Attributes are not decoded (use {!attrs_jsont}
923923- separately on the [.zattrs] file). *)
921921+(** Codec for a Zarr v2 [.zarray] file. Produces a {!V2_node.t} with [`Array]
922922+ kind. Attributes are not decoded (use {!attrs_jsont} separately on the
923923+ [.zattrs] file). *)
924924925925val v2_group_jsont : V2_node.t Jsont.t
926926-(** Codec for a Zarr v2 [.zgroup] file. Produces a {!V2_node.t}
927927- with [`Group] kind. Encodes as [{"zarr_format": 2}]. *)
926926+(** Codec for a Zarr v2 [.zgroup] file. Produces a {!V2_node.t} with [`Group]
927927+ kind. Encodes as [{"zarr_format": 2}]. *)
928928929929val v3_jsont : V3_node.t Jsont.t
930930-(** Codec for a Zarr v3 [zarr.json] file. Dispatches on ["node_type"]:
931931- arrays are fully decoded via {!V3.array_meta_jsont}; groups produce
932932- a [`Group] node. The ["attributes"] sub-object is decoded via
933933- {!attrs_jsont}. *)
930930+(** Codec for a Zarr v3 [zarr.json] file. Dispatches on ["node_type"]: arrays
931931+ are fully decoded via {!V3.array_meta_jsont}; groups produce a [`Group]
932932+ node. The ["attributes"] sub-object is decoded via {!attrs_jsont}. *)
934933935934(** {1:dispatch Unified dispatch} *)
936935···938937(** A zarr node of either version. *)
939938940939val jsont : t Jsont.t
941941-(** Top-level dispatch codec. Inspects ["zarr_format"] to choose v2 or
942942- v3, then dispatches to the appropriate node codec. V2 arrays are
943943- distinguished from groups by the presence of ["shape"]. *)
940940+(** Top-level dispatch codec. Inspects ["zarr_format"] to choose v2 or v3, then
941941+ dispatches to the appropriate node codec. V2 arrays are distinguished from
942942+ groups by the presence of ["shape"]. *)
944943945944(** {1:consolidated Consolidated metadata}
946945947947- Consolidated metadata allows loading the metadata for an entire
948948- hierarchy with a single read, avoiding per-node HTTP requests for
949949- remote stores. *)
946946+ Consolidated metadata allows loading the metadata for an entire hierarchy
947947+ with a single read, avoiding per-node HTTP requests for remote stores. *)
950948951951-(** V3 consolidated metadata, stored inline in a group's [zarr.json]
952952- as an optional ["consolidated_metadata"] field.
949949+(** V3 consolidated metadata, stored inline in a group's [zarr.json] as an
950950+ optional ["consolidated_metadata"] field.
953951954954- See {{:https://github.com/zarr-developers/zarr-specs/pull/309}
955955- zarr-specs PR 309}. The ["metadata"] map uses relative paths as
956956- keys and full [zarr.json] objects as values. For example, a
957957- hierarchy [A/B/x] consolidated at [A] would have key ["B/x"]. *)
952952+ See
953953+ {{:https://github.com/zarr-developers/zarr-specs/pull/309} zarr-specs PR
954954+ 309}. The ["metadata"] map uses relative paths as keys and full [zarr.json]
955955+ objects as values. For example, a hierarchy [A/B/x] consolidated at [A]
956956+ would have key ["B/x"]. *)
958957module Consolidated : sig
959958 type t
959959+960960 val metadata : t -> (string * V3_node.t) list
961961 (** Mapping from relative node path to decoded metadata. *)
962962963963 val kind : t -> string
964964- (** Storage kind. Currently always ["inline"]. *)
964964+ (** Storage kind. Currently always ["inline"]. *)
965965966966 val jsont : t Jsont.t
967967end
968968969969-(** V2 consolidated metadata, stored in a [.zmetadata] file at the
970970- store root.
969969+(** V2 consolidated metadata, stored in a [.zmetadata] file at the store root.
971970972971 The file contains a ["metadata"] object mapping flat keys like
973973- ["array1/.zarray"] and ["array1/.zattrs"] to their JSON contents,
974974- plus a ["zarr_consolidated_format"] version number (currently [1]).
975975- This codec groups the flat keys by path prefix and decodes each
976976- group into a {!V2_node.t} with optional {!Attrs.t}. *)
972972+ ["array1/.zarray"] and ["array1/.zattrs"] to their JSON contents, plus a
973973+ ["zarr_consolidated_format"] version number (currently [1]). This codec
974974+ groups the flat keys by path prefix and decodes each group into a
975975+ {!V2_node.t} with optional {!Attrs.t}. *)
977976module V2_consolidated : sig
978977 type entry = {
979979- path : string; (** Relative path within the store. *)
978978+ path : string; (** Relative path within the store. *)
980979 node : V2_node.t; (** Decoded node metadata. *)
981980 attrs : Attrs.t option; (** Decoded [.zattrs], if present. *)
982981 }
983982984983 type t
984984+985985 val entries : t -> entry list
986986 (** All entries, sorted by path. *)
987987···996996type probe_result = {
997997 node : t;
998998 attrs : Attrs.t option;
999999- (** For v2, the separately-fetched [.zattrs] if present. For v3,
10001000- [None] (attributes are inline in [zarr.json]). *)
999999+ (** For v2, the separately-fetched [.zattrs] if present. For v3, [None]
10001000+ (attributes are inline in [zarr.json]). *)
10011001 consolidated : [ `V3 of Consolidated.t | `V2 of V2_consolidated.t ] option;
10021002- (** Consolidated metadata, if present. *)
10021002+ (** Consolidated metadata, if present. *)
10031003 children : (string * probe_result) list;
10041004- (** Recursively probed children. Populated from consolidated
10051005- metadata when available. *)
10041004+ (** Recursively probed children. Populated from consolidated metadata when
10051005+ available. *)
10061006}
10071007(** The result of probing a zarr store path. *)
10081008···10121012 (probe_result, string) result
10131013(** [probe ~read path] probes the zarr store rooted at [path].
1014101410151015- [read relpath] fetches a file relative to the store root. It
10161016- should return [Ok contents] or [Error msg].
10151015+ [read relpath] fetches a file relative to the store root. It should return
10161016+ [Ok contents] or [Error msg].
1017101710181018 Probing order:
10191019 + [zarr.json] (v3), checking for ["consolidated_metadata"]
10201020 + [.zarray] (v2 array), with optional [.zattrs]
10211021 + [.zgroup] (v2 group), with optional [.zattrs] and [.zmetadata]
1022102210231023- When consolidated metadata is present, {!probe_result.children} is
10241024- populated by recursively grouping entries by path component.
10231023+ When consolidated metadata is present, {!probe_result.children} is populated
10241024+ by recursively grouping entries by path component.
1025102510261026 Returns [Error] if no zarr metadata files can be read. *)
10271027···10401040(** Pretty-print decoded attributes: conventions, then unknown keys. *)
1041104110421042val pp_probe_result : Format.formatter -> probe_result -> unit
10431043-(** Pretty-print a probe result as a tree with types, shapes,
10441044- conventions, and unknown attributes. Example output:
10451045- {v
10461046-[group]
10471047- geoemb: pixel 128d model=https://... dtype=int8 gsd=10
10481048- quantization: per_pixel_scale float32 -> int8 scale_array=scales
10491049- utm01 [group]
10501050- proj: code=EPSG:32601
10511051- spatial: dims=[y,x] bbox=[...] transform=[...] shape=[1290240x65536]
10521052- embeddings [array int8 9x128x1290240x65536]
10531053- v} *)
10431043+(** Pretty-print a probe result as a tree with types, shapes, conventions, and
10441044+ unknown attributes. *)
+210-158
test/test_zarr_jsont.ml
···22[@@@ai_model "claude-opus-4"]
33[@@@ai_provider "Anthropic"]
4455-let decode c s = match Jsont_bytesrw.decode_string c s with
66- | Ok v -> v | Error e -> failwith e
55+let decode c s =
66+ match Jsont_bytesrw.decode_string c s with Ok v -> v | Error e -> failwith e
7788-let encode c v = match Jsont_bytesrw.encode_string c v with
99- | Ok s -> s | Error e -> failwith e
88+let encode c v =
99+ match Jsont_bytesrw.encode_string c v with Ok s -> s | Error e -> failwith e
10101111let test_other_codec () =
1212 let json = {|{"id":"custom_codec","param1":42,"param2":"hello"}|} in
···1818 print_endline "test_other_codec: ok"
19192020let test_other_ext () =
2121- let json = {|{"name":"custom.ext","configuration":{"key":"val"},"must_understand":false}|} in
2121+ let json =
2222+ {|{"name":"custom.ext","configuration":{"key":"val"},"must_understand":false}|}
2323+ in
2224 let v = decode Zarr_jsont.Other_ext.jsont json in
2325 assert (Zarr_jsont.Other_ext.name v = "custom.ext");
2426 assert (Zarr_jsont.Other_ext.must_understand v = false);
···9496 (* structured *)
9597 let v = decode dt {|[["x","<f4"],["y","<f4",[3]]]|} in
9698 (match v with
9797- | `Structured fields ->
9898- assert (List.length fields = 2);
9999- let (n1, t1, s1) = List.nth fields 0 in
100100- assert (n1 = "x" && t1 = `Float (`Little, 4) && s1 = None);
101101- let (n2, t2, s2) = List.nth fields 1 in
102102- assert (n2 = "y" && t2 = `Float (`Little, 4) && s2 = Some [3])
103103- | _ -> assert false);
9999+ | `Structured fields ->
100100+ assert (List.length fields = 2);
101101+ let n1, t1, s1 = List.nth fields 0 in
102102+ assert (n1 = "x" && t1 = `Float (`Little, 4) && s1 = None);
103103+ let n2, t2, s2 = List.nth fields 1 in
104104+ assert (n2 = "y" && t2 = `Float (`Little, 4) && s2 = Some [ 3 ])
105105+ | _ -> assert false);
104106 (* roundtrip simple *)
105107 let json' = encode dt (`Float (`Little, 8)) in
106108 assert (decode dt json' = `Float (`Little, 8));
107109 (* roundtrip structured *)
108108- let s = `Structured [("x", `Float (`Little, 4), None);
109109- ("y", `Int (`Big, 2), Some [3; 2])] in
110110+ let s =
111111+ `Structured
112112+ [ ("x", `Float (`Little, 4), None); ("y", `Int (`Big, 2), Some [ 3; 2 ]) ]
113113+ in
110114 let json' = encode dt s in
111115 assert (decode dt json' = s);
112116 print_endline "test_dtype: ok"
···117121 let json = {|{"id":"blosc","cname":"lz4","clevel":5,"shuffle":1}|} in
118122 let v = decode c json in
119123 (match v with
120120- | `Blosc b ->
121121- assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4");
122122- assert (Zarr_jsont.V2.Compressor.Blosc.clevel b = 5);
123123- assert (Zarr_jsont.V2.Compressor.Blosc.shuffle b = 1)
124124- | _ -> assert false);
124124+ | `Blosc b ->
125125+ assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4");
126126+ assert (Zarr_jsont.V2.Compressor.Blosc.clevel b = 5);
127127+ assert (Zarr_jsont.V2.Compressor.Blosc.shuffle b = 1)
128128+ | _ -> assert false);
125129 (* zlib *)
126130 let json = {|{"id":"zlib","level":1}|} in
127131 let v = decode c json in
128132 (match v with
129129- | `Zlib z -> assert (Zarr_jsont.V2.Compressor.Zlib.level z = 1)
130130- | _ -> assert false);
133133+ | `Zlib z -> assert (Zarr_jsont.V2.Compressor.Zlib.level z = 1)
134134+ | _ -> assert false);
131135 (* unknown compressor *)
132136 let json = {|{"id":"lzma","preset":6}|} in
133137 let v = decode c json in
134138 (match v with
135135- | `Other o -> assert (Zarr_jsont.Other_codec.name o = "lzma")
136136- | _ -> assert false);
139139+ | `Other o -> assert (Zarr_jsont.Other_codec.name o = "lzma")
140140+ | _ -> assert false);
137141 print_endline "test_v2_compressor: ok"
138142139143let test_v2_filter () =
···141145 let json = {|{"id":"delta","dtype":"<f8","astype":"<f4"}|} in
142146 let v = decode f json in
143147 (match v with
144144- | `Delta d ->
145145- assert (Zarr_jsont.V2.Filter.Delta.dtype d = "<f8");
146146- assert (Zarr_jsont.V2.Filter.Delta.astype d = Some "<f4")
147147- | _ -> assert false);
148148+ | `Delta d ->
149149+ assert (Zarr_jsont.V2.Filter.Delta.dtype d = "<f8");
150150+ assert (Zarr_jsont.V2.Filter.Delta.astype d = Some "<f4")
151151+ | _ -> assert false);
148152 (* unknown filter *)
149153 let json = {|{"id":"quantize","digits":10}|} in
150154 let v = decode f json in
151155 (match v with
152152- | `Other o -> assert (Zarr_jsont.Other_codec.name o = "quantize")
153153- | _ -> assert false);
156156+ | `Other o -> assert (Zarr_jsont.Other_codec.name o = "quantize")
157157+ | _ -> assert false);
154158 print_endline "test_v2_filter: ok"
155159156160let test_v2_array () =
157157- let json = {|{
161161+ let json =
162162+ {|{
158163 "zarr_format": 2,
159164 "shape": [10000, 10000],
160165 "chunks": [1000, 1000],
···163168 "fill_value": "NaN",
164169 "order": "C",
165170 "filters": [{"id": "delta", "dtype": "<f8", "astype": "<f4"}]
166166- }|} in
171171+ }|}
172172+ in
167173 let v = decode Zarr_jsont.V2.array_meta_jsont json in
168168- assert (Zarr_jsont.V2.Array_meta.shape v = [10000; 10000]);
169169- assert (Zarr_jsont.V2.Array_meta.chunks v = [1000; 1000]);
174174+ assert (Zarr_jsont.V2.Array_meta.shape v = [ 10000; 10000 ]);
175175+ assert (Zarr_jsont.V2.Array_meta.chunks v = [ 1000; 1000 ]);
170176 assert (Zarr_jsont.V2.Array_meta.dtype v = `Float (`Little, 8));
171177 assert (Zarr_jsont.V2.Array_meta.order v = `C);
172178 (match Zarr_jsont.V2.Array_meta.compressor v with
173173- | Some (`Blosc b) ->
174174- assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4")
175175- | _ -> assert false);
179179+ | Some (`Blosc b) -> assert (Zarr_jsont.V2.Compressor.Blosc.cname b = "lz4")
180180+ | _ -> assert false);
176181 (match Zarr_jsont.V2.Array_meta.filters v with
177177- | Some [(`Delta _)] -> ()
178178- | _ -> assert false);
182182+ | Some [ `Delta _ ] -> ()
183183+ | _ -> assert false);
179184 (match Zarr_jsont.V2.Array_meta.fill_value v with
180180- | `Float f -> assert (Float.is_nan f)
181181- | _ -> assert false);
185185+ | `Float f -> assert (Float.is_nan f)
186186+ | _ -> assert false);
182187 (* roundtrip *)
183188 let json' = encode Zarr_jsont.V2.array_meta_jsont v in
184189 let _ = decode Zarr_jsont.V2.array_meta_jsont json' in
185190 (* null compressor and filters *)
186186- let json2 = {|{
191191+ let json2 =
192192+ {|{
187193 "zarr_format": 2,
188194 "shape": [20, 20],
189195 "chunks": [10, 10],
···192198 "fill_value": 42,
193199 "order": "C",
194200 "filters": null
195195- }|} in
201201+ }|}
202202+ in
196203 let v2 = decode Zarr_jsont.V2.array_meta_jsont json2 in
197204 assert (Zarr_jsont.V2.Array_meta.compressor v2 = None);
198205 assert (Zarr_jsont.V2.Array_meta.filters v2 = None);
···203210 (* bytes *)
204211 let v = decode c {|{"name":"bytes","configuration":{"endian":"little"}}|} in
205212 (match v with
206206- | `Bytes b -> assert (Zarr_jsont.V3.Codec.Bytes.endian b = Some `Little)
207207- | _ -> assert false);
213213+ | `Bytes b -> assert (Zarr_jsont.V3.Codec.Bytes.endian b = Some `Little)
214214+ | _ -> assert false);
208215 (* gzip *)
209216 let v = decode c {|{"name":"gzip","configuration":{"level":5}}|} in
210217 (match v with
211211- | `Gzip g -> assert (Zarr_jsont.V3.Codec.Gzip.level g = 5)
212212- | _ -> assert false);
218218+ | `Gzip g -> assert (Zarr_jsont.V3.Codec.Gzip.level g = 5)
219219+ | _ -> assert false);
213220 (* blosc *)
214214- let v = decode c {|{"name":"blosc","configuration":{"cname":"lz4","clevel":5,"shuffle":"shuffle","typesize":4,"blocksize":0}}|} in
221221+ let v =
222222+ decode c
223223+ {|{"name":"blosc","configuration":{"cname":"lz4","clevel":5,"shuffle":"shuffle","typesize":4,"blocksize":0}}|}
224224+ in
215225 (match v with
216216- | `Blosc b ->
217217- assert (Zarr_jsont.V3.Codec.Blosc.cname b = "lz4");
218218- assert (Zarr_jsont.V3.Codec.Blosc.shuffle b = `Shuffle)
219219- | _ -> assert false);
226226+ | `Blosc b ->
227227+ assert (Zarr_jsont.V3.Codec.Blosc.cname b = "lz4");
228228+ assert (Zarr_jsont.V3.Codec.Blosc.shuffle b = `Shuffle)
229229+ | _ -> assert false);
220230 (* crc32c *)
221231 let v = decode c {|{"name":"crc32c"}|} in
222232 assert (v = `Crc32c);
223233 (* transpose *)
224234 let v = decode c {|{"name":"transpose","configuration":{"order":[1,0,2]}}|} in
225235 (match v with
226226- | `Transpose t -> assert (Zarr_jsont.V3.Codec.Transpose.order t = [1;0;2])
227227- | _ -> assert false);
236236+ | `Transpose t -> assert (Zarr_jsont.V3.Codec.Transpose.order t = [ 1; 0; 2 ])
237237+ | _ -> assert false);
228238 (* unknown *)
229239 let v = decode c {|{"name":"zstd","configuration":{"level":3}}|} in
230240 (match v with
231231- | `Other o -> assert (Zarr_jsont.Other_ext.name o = "zstd")
232232- | _ -> assert false);
241241+ | `Other o -> assert (Zarr_jsont.Other_ext.name o = "zstd")
242242+ | _ -> assert false);
233243 (* sharding *)
234234- let v = decode c {|{"name":"sharding_indexed","configuration":{"chunk_shape":[32,32],"codecs":[{"name":"bytes","configuration":{"endian":"little"}}],"index_location":"end"}}|} in
244244+ let v =
245245+ decode c
246246+ {|{"name":"sharding_indexed","configuration":{"chunk_shape":[32,32],"codecs":[{"name":"bytes","configuration":{"endian":"little"}}],"index_location":"end"}}|}
247247+ in
235248 (match v with
236236- | `Sharding s ->
237237- assert (Zarr_jsont.V3.Codec.Sharding.chunk_shape s = [32; 32]);
238238- assert (List.length (Zarr_jsont.V3.Codec.Sharding.codecs s) = 1);
239239- assert (Zarr_jsont.V3.Codec.Sharding.index_location s = `End)
240240- | _ -> assert false);
249249+ | `Sharding s ->
250250+ assert (Zarr_jsont.V3.Codec.Sharding.chunk_shape s = [ 32; 32 ]);
251251+ assert (List.length (Zarr_jsont.V3.Codec.Sharding.codecs s) = 1);
252252+ assert (Zarr_jsont.V3.Codec.Sharding.index_location s = `End)
253253+ | _ -> assert false);
241254 print_endline "test_v3_codecs: ok"
242255243256let test_v3_data_type () =
···248261 assert (decode dt {|"r16"|} = `Raw 16);
249262 let v = decode dt {|{"name":"datetime","configuration":{"unit":"ns"}}|} in
250263 (match v with
251251- | `Other o -> assert (Zarr_jsont.Other_ext.name o = "datetime")
252252- | _ -> assert false);
264264+ | `Other o -> assert (Zarr_jsont.Other_ext.name o = "datetime")
265265+ | _ -> assert false);
253266 print_endline "test_v3_data_type: ok"
254267255268let test_v3_array_meta () =
256256- let json = {|{
269269+ let json =
270270+ {|{
257271 "zarr_format": 3,
258272 "node_type": "array",
259273 "shape": [10000, 1000],
···264278 "codecs": [{"name": "bytes", "configuration": {"endian": "little"}}],
265279 "fill_value": "NaN",
266280 "attributes": {"foo": 42}
267267- }|} in
281281+ }|}
282282+ in
268283 let v = decode Zarr_jsont.V3.array_meta_jsont json in
269269- assert (Zarr_jsont.V3.Array_meta.shape v = [10000; 1000]);
284284+ assert (Zarr_jsont.V3.Array_meta.shape v = [ 10000; 1000 ]);
270285 assert (Zarr_jsont.V3.Array_meta.data_type v = `Float64);
271271- assert (Zarr_jsont.V3.Array_meta.dimension_names v = Some [Some "rows"; Some "columns"]);
286286+ assert (
287287+ Zarr_jsont.V3.Array_meta.dimension_names v
288288+ = Some [ Some "rows"; Some "columns" ]);
272289 (match Zarr_jsont.V3.Array_meta.chunk_grid v with
273273- | `Regular r -> assert (Zarr_jsont.V3.Chunk_grid.Regular.chunk_shape r = [1000; 100])
274274- | _ -> assert false);
290290+ | `Regular r ->
291291+ assert (Zarr_jsont.V3.Chunk_grid.Regular.chunk_shape r = [ 1000; 100 ])
292292+ | _ -> assert false);
275293 (match Zarr_jsont.V3.Array_meta.chunk_key_encoding v with
276276- | `Default d -> assert (Zarr_jsont.V3.Chunk_key_encoding.Default.separator d = `Slash)
277277- | _ -> assert false);
294294+ | `Default d ->
295295+ assert (Zarr_jsont.V3.Chunk_key_encoding.Default.separator d = `Slash)
296296+ | _ -> assert false);
278297 print_endline "test_v3_array_meta: ok"
279298280299let test_conv_proj () =
···286305 print_endline "test_conv_proj: ok"
287306288307let test_conv_spatial () =
289289- let json = {|{
308308+ let json =
309309+ {|{
290310 "spatial:dimensions": ["Y", "X"],
291311 "spatial:bbox": [-180.0, -90.0, 180.0, 90.0],
292312 "spatial:transform": [1.0, 0.0, 0.0, 0.0, -1.0, 90.0],
293313 "spatial:registration": "pixel"
294294- }|} in
314314+ }|}
315315+ in
295316 let v = decode Zarr_jsont.Conv.Spatial.jsont json in
296296- assert (Zarr_jsont.Conv.Spatial.dimensions v = ["Y"; "X"]);
317317+ assert (Zarr_jsont.Conv.Spatial.dimensions v = [ "Y"; "X" ]);
297318 assert (Zarr_jsont.Conv.Spatial.registration v = Some `Pixel);
298298- assert (Zarr_jsont.Conv.Spatial.bbox v = Some [-180.0; -90.0; 180.0; 90.0]);
319319+ assert (Zarr_jsont.Conv.Spatial.bbox v = Some [ -180.0; -90.0; 180.0; 90.0 ]);
299320 print_endline "test_conv_spatial: ok"
300321301322let test_conv_multiscales () =
302302- let json = {|{
323323+ let json =
324324+ {|{
303325 "layout": [
304326 {"asset": "0", "transform": {"scale": [1.0, 1.0]}},
305327 {"asset": "1", "derived_from": "0", "transform": {"scale": [2.0, 2.0]}, "resampling_method": "average"}
306328 ],
307329 "resampling_method": "average"
308308- }|} in
330330+ }|}
331331+ in
309332 let v = decode Zarr_jsont.Conv.Multiscales.jsont json in
310333 let layout = Zarr_jsont.Conv.Multiscales.layout v in
311334 assert (List.length layout = 2);
···314337 assert (Zarr_jsont.Conv.Multiscales.Layout_item.derived_from item0 = None);
315338 let item1 = List.nth layout 1 in
316339 assert (Zarr_jsont.Conv.Multiscales.Layout_item.derived_from item1 = Some "0");
317317- assert (Zarr_jsont.Conv.Multiscales.Layout_item.resampling_method item1 = Some "average");
340340+ assert (
341341+ Zarr_jsont.Conv.Multiscales.Layout_item.resampling_method item1
342342+ = Some "average");
318343 print_endline "test_conv_multiscales: ok"
319344320345let test_attrs () =
321321- let json = {|{
346346+ let json =
347347+ {|{
322348 "zarr_conventions": [
323349 {"uuid": "f17cb550-5864-4468-aeb7-f3180cfb622f", "name": "proj:", "description": "CRS info"}
324350 ],
···326352 "spatial:dimensions": ["Y", "X"],
327353 "spatial:transform": [10.0, 0.0, 0.0, 0.0, -10.0, 100.0],
328354 "custom_key": "custom_value"
329329- }|} in
355355+ }|}
356356+ in
330357 let v = decode Zarr_jsont.attrs_jsont json in
331358 (match Zarr_jsont.Attrs.proj v with
332332- | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:3857")
333333- | None -> assert false);
359359+ | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:3857")
360360+ | None -> assert false);
334361 (match Zarr_jsont.Attrs.spatial v with
335335- | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = ["Y"; "X"])
336336- | None -> assert false);
362362+ | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = [ "Y"; "X" ])
363363+ | None -> assert false);
337364 assert (Zarr_jsont.Attrs.multiscales v = None);
338365 assert (List.length (Zarr_jsont.Attrs.conventions v) >= 1);
339366 (* roundtrip *)
340367 let json' = encode Zarr_jsont.attrs_jsont v in
341368 let v' = decode Zarr_jsont.attrs_jsont json' in
342369 (match Zarr_jsont.Attrs.proj v' with
343343- | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:3857")
344344- | None -> assert false);
370370+ | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:3857")
371371+ | None -> assert false);
345372 (match Zarr_jsont.Attrs.spatial v' with
346346- | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = ["Y"; "X"])
347347- | None -> assert false);
373373+ | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = [ "Y"; "X" ])
374374+ | None -> assert false);
348375 (* empty attrs *)
349376 let e = Zarr_jsont.Attrs.empty in
350377 assert (Zarr_jsont.Attrs.conventions e = []);
···354381 print_endline "test_attrs: ok"
355382356383let test_v2_node_array () =
357357- let json = {|{
384384+ let json =
385385+ {|{
358386 "zarr_format": 2,
359387 "shape": [100, 100],
360388 "chunks": [10, 10],
···363391 "fill_value": 42,
364392 "order": "C",
365393 "filters": null
366366- }|} in
394394+ }|}
395395+ in
367396 let v = decode Zarr_jsont.v2_array_jsont json in
368397 (match Zarr_jsont.V2_node.kind v with
369369- | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [100; 100])
370370- | `Group -> assert false);
398398+ | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [ 100; 100 ])
399399+ | `Group -> assert false);
371400 assert (Zarr_jsont.Attrs.proj (Zarr_jsont.V2_node.attrs v) = None);
372401 (* roundtrip *)
373402 let json' = encode Zarr_jsont.v2_array_jsont v in
374403 let v' = decode Zarr_jsont.v2_array_jsont json' in
375404 (match Zarr_jsont.V2_node.kind v' with
376376- | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [100; 100])
377377- | `Group -> assert false);
405405+ | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [ 100; 100 ])
406406+ | `Group -> assert false);
378407 print_endline "test_v2_node_array: ok"
379408380409let test_v2_group () =
···389418 print_endline "test_v2_group: ok"
390419391420let test_v3_node_group () =
392392- let json = {|{
421421+ let json =
422422+ {|{
393423 "zarr_format": 3,
394424 "node_type": "group",
395425 "attributes": {
396426 "proj:code": "EPSG:4326",
397427 "spatial:dimensions": ["Y", "X"]
398428 }
399399- }|} in
429429+ }|}
430430+ in
400431 let v = decode Zarr_jsont.v3_jsont json in
401432 assert (Zarr_jsont.V3_node.kind v = `Group);
402433 (match Zarr_jsont.Attrs.proj (Zarr_jsont.V3_node.attrs v) with
403403- | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
404404- | None -> assert false);
434434+ | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
435435+ | None -> assert false);
405436 (match Zarr_jsont.Attrs.spatial (Zarr_jsont.V3_node.attrs v) with
406406- | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = ["Y"; "X"])
407407- | None -> assert false);
437437+ | Some s -> assert (Zarr_jsont.Conv.Spatial.dimensions s = [ "Y"; "X" ])
438438+ | None -> assert false);
408439 (* roundtrip *)
409440 let json' = encode Zarr_jsont.v3_jsont v in
410441 let v' = decode Zarr_jsont.v3_jsont json' in
411442 assert (Zarr_jsont.V3_node.kind v' = `Group);
412443 (match Zarr_jsont.Attrs.proj (Zarr_jsont.V3_node.attrs v') with
413413- | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
414414- | None -> assert false);
444444+ | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
445445+ | None -> assert false);
415446 print_endline "test_v3_node_group: ok"
416447417448let test_v3_node_array () =
418418- let json = {|{
449449+ let json =
450450+ {|{
419451 "zarr_format": 3,
420452 "node_type": "array",
421453 "shape": [100],
···424456 "chunk_key_encoding": {"name": "default", "configuration": {"separator": "/"}},
425457 "codecs": [{"name": "bytes", "configuration": {"endian": "little"}}],
426458 "fill_value": 0
427427- }|} in
459459+ }|}
460460+ in
428461 let v = decode Zarr_jsont.v3_jsont json in
429462 (match Zarr_jsont.V3_node.kind v with
430430- | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [100])
431431- | `Group -> assert false);
463463+ | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [ 100 ])
464464+ | `Group -> assert false);
432465 assert (Zarr_jsont.Attrs.proj (Zarr_jsont.V3_node.attrs v) = None);
433466 (* roundtrip *)
434467 let json' = encode Zarr_jsont.v3_jsont v in
435468 let v' = decode Zarr_jsont.v3_jsont json' in
436469 (match Zarr_jsont.V3_node.kind v' with
437437- | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [100])
438438- | `Group -> assert false);
470470+ | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [ 100 ])
471471+ | `Group -> assert false);
439472 print_endline "test_v3_node_array: ok"
440473441474let test_v3_node_array_with_attrs () =
442442- let json = {|{
475475+ let json =
476476+ {|{
443477 "zarr_format": 3,
444478 "node_type": "array",
445479 "shape": [50, 50],
···451485 "attributes": {
452486 "proj:code": "EPSG:4326"
453487 }
454454- }|} in
488488+ }|}
489489+ in
455490 let v = decode Zarr_jsont.v3_jsont json in
456491 (match Zarr_jsont.V3_node.kind v with
457457- | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [50; 50])
458458- | `Group -> assert false);
492492+ | `Array a -> assert (Zarr_jsont.V3.Array_meta.shape a = [ 50; 50 ])
493493+ | `Group -> assert false);
459494 (match Zarr_jsont.Attrs.proj (Zarr_jsont.V3_node.attrs v) with
460460- | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
461461- | None -> assert false);
495495+ | Some p -> assert (Zarr_jsont.Conv.Proj.code p = Some "EPSG:4326")
496496+ | None -> assert false);
462497 print_endline "test_v3_node_array_with_attrs: ok"
463498464499let test_dispatch_v2_array () =
465465- let json = {|{
500500+ let json =
501501+ {|{
466502 "zarr_format": 2,
467503 "shape": [20, 20],
468504 "chunks": [10, 10],
···471507 "fill_value": 42,
472508 "order": "C",
473509 "filters": null
474474- }|} in
510510+ }|}
511511+ in
475512 let v = decode Zarr_jsont.jsont json in
476513 (match v with
477477- | `V2 node ->
478478- (match Zarr_jsont.V2_node.kind node with
479479- | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [20; 20])
514514+ | `V2 node -> (
515515+ match Zarr_jsont.V2_node.kind node with
516516+ | `Array a -> assert (Zarr_jsont.V2.Array_meta.shape a = [ 20; 20 ])
480517 | `Group -> assert false)
481481- | `V3 _ -> assert false);
518518+ | `V3 _ -> assert false);
482519 print_endline "test_dispatch_v2_array: ok"
483520484521let test_dispatch_v2_group () =
485522 let json = {|{"zarr_format": 2}|} in
486523 let v = decode Zarr_jsont.jsont json in
487524 (match v with
488488- | `V2 node -> assert (Zarr_jsont.V2_node.kind node = `Group)
489489- | `V3 _ -> assert false);
525525+ | `V2 node -> assert (Zarr_jsont.V2_node.kind node = `Group)
526526+ | `V3 _ -> assert false);
490527 print_endline "test_dispatch_v2_group: ok"
491528492529let test_dispatch_v3_array () =
493493- let json = {|{
530530+ let json =
531531+ {|{
494532 "zarr_format": 3,
495533 "node_type": "array",
496534 "shape": [100],
···499537 "chunk_key_encoding": {"name": "default", "configuration": {"separator": "/"}},
500538 "codecs": [{"name": "bytes", "configuration": {"endian": "little"}}],
501539 "fill_value": 0
502502- }|} in
540540+ }|}
541541+ in
503542 let v = decode Zarr_jsont.jsont json in
504543 (match v with
505505- | `V3 node ->
506506- (match Zarr_jsont.V3_node.kind node with
544544+ | `V3 node -> (
545545+ match Zarr_jsont.V3_node.kind node with
507546 | `Array a -> assert (Zarr_jsont.V3.Array_meta.data_type a = `Int32)
508547 | `Group -> assert false)
509509- | `V2 _ -> assert false);
548548+ | `V2 _ -> assert false);
510549 print_endline "test_dispatch_v3_array: ok"
511550512551let test_dispatch_v3_group () =
513552 let json = {|{"zarr_format": 3, "node_type": "group"}|} in
514553 let v = decode Zarr_jsont.jsont json in
515554 (match v with
516516- | `V3 node -> assert (Zarr_jsont.V3_node.kind node = `Group)
517517- | `V2 _ -> assert false);
555555+ | `V3 node -> assert (Zarr_jsont.V3_node.kind node = `Group)
556556+ | `V2 _ -> assert false);
518557 print_endline "test_dispatch_v3_group: ok"
519558520559let () = test_other_codec ()
···547586 let v = decode Zarr_jsont.v3_jsont json_str in
548587 let json' = encode Zarr_jsont.v3_jsont v in
549588 let v' = decode Zarr_jsont.v3_jsont json' in
550550- (match Zarr_jsont.V3_node.kind v, Zarr_jsont.V3_node.kind v' with
551551- | `Array a, `Array a' ->
552552- assert (Zarr_jsont.V3.Array_meta.shape a = Zarr_jsont.V3.Array_meta.shape a');
553553- assert (Zarr_jsont.V3.Array_meta.data_type a = Zarr_jsont.V3.Array_meta.data_type a')
554554- | `Group, `Group -> ()
555555- | _ -> assert false)
589589+ match (Zarr_jsont.V3_node.kind v, Zarr_jsont.V3_node.kind v') with
590590+ | `Array a, `Array a' ->
591591+ assert (
592592+ Zarr_jsont.V3.Array_meta.shape a = Zarr_jsont.V3.Array_meta.shape a');
593593+ assert (
594594+ Zarr_jsont.V3.Array_meta.data_type a
595595+ = Zarr_jsont.V3.Array_meta.data_type a')
596596+ | `Group, `Group -> ()
597597+ | _ -> assert false
556598557599let test_roundtrip_v3_array () =
558558- roundtrip_v3 {|{
600600+ roundtrip_v3
601601+ {|{
559602 "zarr_format": 3,
560603 "node_type": "array",
561604 "shape": [10000, 1000],
···570613 print_endline "test_roundtrip_v3_array: ok"
571614572615let test_roundtrip_v3_group_with_convs () =
573573- roundtrip_v3 {|{
616616+ roundtrip_v3
617617+ {|{
574618 "zarr_format": 3,
575619 "node_type": "group",
576620 "attributes": {
···586630 print_endline "test_roundtrip_v3_group_with_convs: ok"
587631588632let test_roundtrip_v2 () =
589589- let json = {|{
633633+ let json =
634634+ {|{
590635 "zarr_format": 2,
591636 "shape": [10000, 10000],
592637 "chunks": [1000, 1000],
···595640 "fill_value": "NaN",
596641 "order": "C",
597642 "filters": [{"id": "delta", "dtype": "<f8", "astype": "<f4"}]
598598- }|} in
643643+ }|}
644644+ in
599645 let v = decode Zarr_jsont.v2_array_jsont json in
600646 let json' = encode Zarr_jsont.v2_array_jsont v in
601647 let v' = decode Zarr_jsont.v2_array_jsont json' in
602602- let get_shape n = match Zarr_jsont.V2_node.kind n with
648648+ let get_shape n =
649649+ match Zarr_jsont.V2_node.kind n with
603650 | `Array a -> Zarr_jsont.V2.Array_meta.shape a
604651 | `Group -> failwith "expected array"
605652 in
···607654 print_endline "test_roundtrip_v2: ok"
608655609656let test_roundtrip_multiscales () =
610610- roundtrip_v3 {|{
657657+ roundtrip_v3
658658+ {|{
611659 "zarr_format": 3,
612660 "node_type": "group",
613661 "attributes": {
···633681634682let test_unknown_preservation () =
635683 (* V2 array with extra unknown field *)
636636- let json = {|{
684684+ let json =
685685+ {|{
637686 "zarr_format": 2,
638687 "shape": [10],
639688 "chunks": [5],
···643692 "order": "C",
644693 "filters": null,
645694 "custom_extension": {"nested": true}
646646- }|} in
695695+ }|}
696696+ in
647697 let v = decode Zarr_jsont.v2_array_jsont json in
648698 let json' = encode Zarr_jsont.v2_array_jsont v in
649699 let v' = decode Zarr_jsont.v2_array_jsont json' in
650700 (match Zarr_jsont.V2_node.kind v' with
651651- | `Array a ->
652652- let unk = Zarr_jsont.V2.Array_meta.unknown a in
653653- (match unk with
701701+ | `Array a -> (
702702+ let unk = Zarr_jsont.V2.Array_meta.unknown a in
703703+ match unk with
654704 | Jsont.Object (mems, _) ->
655655- assert (List.exists (fun ((k, _), _) -> k = "custom_extension") mems)
705705+ assert (List.exists (fun ((k, _), _) -> k = "custom_extension") mems)
656706 | _ -> assert false)
657657- | _ -> assert false);
707707+ | _ -> assert false);
658708659709 (* V2 compressor with extra unknown fields *)
660660- let json = {|{"id":"blosc","cname":"lz4","clevel":5,"shuffle":1,"extra_param":"test"}|} in
710710+ let json =
711711+ {|{"id":"blosc","cname":"lz4","clevel":5,"shuffle":1,"extra_param":"test"}|}
712712+ in
661713 let v = decode Zarr_jsont.V2.compressor_jsont json in
662714 let json' = encode Zarr_jsont.V2.compressor_jsont v in
663715 let v' = decode Zarr_jsont.V2.compressor_jsont json' in
664716 (match v' with
665665- | `Blosc b ->
666666- let unk = Zarr_jsont.V2.Compressor.Blosc.unknown b in
667667- (match unk with
717717+ | `Blosc b -> (
718718+ let unk = Zarr_jsont.V2.Compressor.Blosc.unknown b in
719719+ match unk with
668720 | Jsont.Object (mems, _) ->
669669- assert (List.exists (fun ((k, _), _) -> k = "extra_param") mems)
721721+ assert (List.exists (fun ((k, _), _) -> k = "extra_param") mems)
670722 | _ -> assert false)
671671- | _ -> assert false);
723723+ | _ -> assert false);
672724673725 (* Attrs with unknown custom key *)
674726 let json = {|{"custom_key": "custom_value", "another": 42}|} in
···677729 let v' = decode Zarr_jsont.attrs_jsont json' in
678730 let unk = Zarr_jsont.Attrs.unknown v' in
679731 (match unk with
680680- | Jsont.Object (mems, _) ->
681681- assert (List.exists (fun ((k, _), _) -> k = "custom_key") mems);
682682- assert (List.exists (fun ((k, _), _) -> k = "another") mems)
683683- | _ -> assert false);
732732+ | Jsont.Object (mems, _) ->
733733+ assert (List.exists (fun ((k, _), _) -> k = "custom_key") mems);
734734+ assert (List.exists (fun ((k, _), _) -> k = "another") mems)
735735+ | _ -> assert false);
684736 print_endline "test_unknown_preservation: ok"
685737686738let () = test_unknown_preservation ()