package zarr

  1. Overview
  2. Docs
An Ocaml implementation of the Zarr V3 specification

Install

Dune Dependency

Authors

Maintainers

Sources

v0.1.0.tar.gz
md5=df6bb0048a4479632c2867d5259c9b27
sha512=341b9db6910a90bb3663c36ae75afb84324c52980b7c6866809424f40cdcc4490eb1f606f5d2a3b1cc91e54671bb09cfc9feae3d9bb55474a66762658d26860c

doc/src/zarr/node.ml.html

Source file node.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
exception Node_invariant

(* Check if the path's name satisfies path invariants *)
let rep_ok name =
  (String.empty <> name) &&
  not (String.contains name '/') &&
  not (String.for_all (Char.equal '.') name) &&
  not (String.starts_with ~prefix:"__" name)

module GroupNode = struct
  type t =
    | Root
    | Cons of t * string

  let create parent name =
    if rep_ok name then Cons (parent, name)
    else raise Node_invariant

  let ( / ) = create

  let root = Root 

  let of_path = function
    | "/" -> Root
    | s ->
      if String.(not @@ starts_with ~prefix:"/" s || ends_with ~suffix:"/" s)
      then raise Node_invariant
      else List.fold_left create Root (List.tl @@ String.split_on_char '/' s)

  let name = function
    | Root -> ""
    | Cons (_, n) -> n

  let parent = function
    | Root -> None
    | Cons (parent, _) -> Some parent

  let rec ( = ) x y =
    match x, y with
    | Root, Root -> true
    | Root, Cons _ | Cons _, Root -> false
    | Cons (p, n), Cons (q, m) -> ( = ) p q && String.equal n m

  let rec fold f acc = function
    | Root -> f acc Root
    | Cons (parent, _) as p -> fold f (f acc p) parent

  let to_path = function
    | Root -> "/"
    | p ->
      String.concat "" @@
      fold (fun acc -> function
        | Root -> acc
        | Cons (_, n) -> "/" :: n :: acc) [] p

  let ancestors p =
    fold (fun acc -> function
      | Root -> acc
      | Cons (parent, _) -> parent :: acc) [] p

  let to_key p =
    let str = to_path p in
    String.(length str - 1 |> sub str 1)

  let to_prefix = function
    | Root -> ""
    | p -> to_key p ^ "/"

  let to_metakey p =
    to_prefix p ^ "zarr.json"

  let is_child_group x y =
    match x, y with
    | _, Root -> false
    | v, Cons (parent, _) -> parent = v

  let show = to_path

  let pp fmt t =
    Format.fprintf fmt "%s" @@ show t
end

module ArrayNode = struct
  type t = {parent : GroupNode.t option; name : string}

  let create g name =
    if rep_ok name then {parent = Some g; name}
    else raise Node_invariant

  let ( / ) = create

  let root = {parent = None; name = ""}

  let of_path p =
    let g = GroupNode.of_path p in
    match GroupNode.parent g with
    | Some _ as parent -> {parent; name = GroupNode.name g}
    | None -> raise Node_invariant
      
  let ( = )
    {parent = p; name = n}
    {parent = q; name = m} = p = q && n = m

  let name {parent = _; name = n} = n

  let parent {parent = p; _} = p

  let to_path {parent = p; name} = match p with
    | None -> "/"
    | Some g when GroupNode.(g = root) -> "/" ^ name
    | Some g -> GroupNode.to_path g ^ "/" ^ name
  
  let ancestors {parent; _} = match parent with
    | None -> []
    | Some g -> g :: GroupNode.ancestors g

  let is_parent {parent; _} y = match parent with
    | None -> false
    | Some g -> GroupNode.(g = y)

  let to_key {parent; name} = match parent with
    | Some g -> GroupNode.to_prefix g ^ name
    | None -> "" 

  let to_metakey = function
    | {parent = None; _} -> "zarr.json"
    | p -> to_key p ^ "/zarr.json"
  
  let show = to_path

  let pp fmt t = Format.fprintf fmt "%s" @@ show t
end
OCaml

Innovation. Community. Security.