···
3
+
module API = Schema.Storage.MakeRPC (Capnp_rpc)
6
-
with type file = [ `File_e62ce624f782d37e ] Capability.t
7
-
and type dir = [ `Directory_8e98f5ea254aace5 ] Capability.t = struct
8
-
module API = Schema.Storage.MakeRPC (Capnp_rpc)
7
+
with type file = API.Client.File.t Capability.t
8
+
and type dir = API.Client.Directory.t Capability.t = struct
type file = API.Client.File.t Capability.t
type dir = API.Client.Directory.t Capability.t
type entry = { name : string; file : file }
···
| Some file -> { name; file }
| None -> failwith "missing entry.file"
21
-
let todo msg = failwith ("Storage." ^ msg)
let open API.Client.Directory.List in
let request = Capability.Request.create_no_args () in
···
let entries = Results.entries_get_list results in
30
-
let create _ = todo "create"
31
-
let open_ _ = todo "open"
32
-
let delete _ = todo "delete"
33
-
let size _ = todo "size"
34
-
let read ?off:_ ?len:_ _ = todo "read"
28
+
let open API.Client.Directory.Create in
29
+
let request, params = Capability.Request.create Params.init_pointer in
30
+
Params.name_set params name;
31
+
let results = Capability.call_for_value_exn t method_id request in
32
+
match Results.file_get results with
34
+
| None -> failwith "create: no file returned"
37
+
let open API.Client.Directory.Open in
38
+
let request, params = Capability.Request.create Params.init_pointer in
39
+
Params.name_set params name;
40
+
let results = Capability.call_for_value_exn t method_id request in
41
+
match Results.file_get results with
43
+
| None -> failwith "open: no file returned"
46
+
let open API.Client.Directory.Delete in
47
+
let request, params = Capability.Request.create Params.init_pointer in
48
+
Params.name_set params name;
49
+
let _ = Capability.call_for_value_exn t method_id request in
53
+
let open API.Client.File.Size in
54
+
let request = Capability.Request.create_no_args () in
55
+
let results = Capability.call_for_value_exn t method_id request in
56
+
Stdint.Int64.of_uint64 (Results.size_get results)
58
+
let read ?off ?len t =
59
+
let open API.Client.File.Read in
60
+
let request, params = Capability.Request.create Params.init_pointer in
64
+
| Some off -> Params.off_set params (Stdint.Int64.to_uint64 off)
69
+
| Some len -> Params.len_set params (Stdint.Int64.to_uint64 len)
71
+
let results = Capability.call_for_value_exn t method_id request in
72
+
Results.data_get results
75
+
let connect net uri f =
let client_vat = Capnp_rpc_unix.client_only_vat ~sw net in
40
-
let sr = Capnp_rpc_unix.Vat.import_exn client_vat uri in
41
-
let entries = Capnp_rpc_unix.with_cap_exn sr Storage.list in
42
-
List.iter (fun { Storage.name; _ } -> Fmt.pr "- %s\n" name) entries
78
+
let client = Capnp_rpc_unix.Vat.import_exn client_vat uri in
79
+
Capnp_rpc_unix.with_cap_exn client f
81
+
let pp_file ppf file = Fmt.pf ppf "[%a]" Capnp_rpc.Capability.pp file
83
+
let pp_entry ppf entry =
84
+
Fmt.pf ppf "%s:%a" entry.Storage.name pp_file entry.file
87
+
connect net uri @@ fun dir ->
88
+
let entries = Storage.list dir in
89
+
Printf.printf "total %d:\n" (List.length entries);
90
+
List.iter (Fmt.pr "- %a\n" pp_entry) entries;
93
+
let create net uri name =
94
+
connect net uri @@ fun dir ->
95
+
let file = Storage.create dir name in
96
+
Fmt.pr "Created file '%s': %a\n" name pp_file file
98
+
let open_file net uri name =
99
+
connect net uri @@ fun dir ->
100
+
let file = Storage.open_ dir name in
101
+
Fmt.pr "Opened file '%s': %a\n" name pp_file file
103
+
let delete net uri name =
104
+
connect net uri @@ fun dir ->
105
+
Storage.delete dir name;
106
+
Fmt.pr "Deleted file '%s'\n" name
108
+
let size net uri name =
109
+
connect net uri @@ fun dir ->
110
+
let file = Storage.open_ dir name in
111
+
let size = Storage.size file in
112
+
Fmt.pr "Size of '%s': %Ld bytes\n" name size
114
+
let read net addr name offset length =
115
+
connect net addr @@ fun dir ->
116
+
let file = Storage.open_ dir name in
117
+
let data = Storage.read ?off:offset ?len:length file in
118
+
Printf.printf "Contents of '%s':\n%s\n" name data
···
let i = Arg.info [] ~docv:"ADDR" ~doc:"Address of server (capnp://...)" in
Arg.(required @@ pos 0 (some Capnp_rpc_unix.sturdy_uri) None i)
131
+
let i = Arg.info [] ~docv:"NAME" ~doc:"Name of the file" in
132
+
Arg.(required @@ pos 1 (some string) None i)
136
+
Arg.info [ "o"; "offset" ] ~docv:"OFFSET"
137
+
~doc:"Offset from where to start reading (default: 0)"
139
+
Arg.(value @@ opt (some int64) None i)
143
+
Arg.info [ "l"; "length" ] ~docv:"LENGTH"
144
+
~doc:"Number of bytes to read (default: all)"
146
+
Arg.(value @@ opt (some int64) None i)
55
-
let doc = "run the client" in
149
+
let doc = "List files in the directory" in
let info = Cmd.info "ls" ~doc in
Cmd.v info Term.(const (ls env#net) $ connect_addr)
59
-
let () = exit @@ Eio_main.run @@ fun env -> Cmd.eval (ls_cmd env)
153
+
let create_cmd env =
154
+
let doc = "Create a new file" in
155
+
let info = Cmd.info "create" ~doc in
156
+
Cmd.v info Term.(const (create env#net) $ connect_addr $ name_arg)
159
+
let doc = "Open an existing file and show its ID" in
160
+
let info = Cmd.info "open" ~doc in
161
+
Cmd.v info Term.(const (open_file env#net) $ connect_addr $ name_arg)
163
+
let delete_cmd env =
164
+
let doc = "Delete a file" in
165
+
let info = Cmd.info "delete" ~doc in
166
+
Cmd.v info Term.(const (delete env#net) $ connect_addr $ name_arg)
169
+
let doc = "Get the size of a file" in
170
+
let info = Cmd.info "size" ~doc in
171
+
Cmd.v info Term.(const (size env#net) $ connect_addr $ name_arg)
174
+
let doc = "Read the contents of a file" in
175
+
let info = Cmd.info "read" ~doc in
178
+
const (read env#net) $ connect_addr $ name_arg $ offset_arg $ length_arg)
181
+
let doc = "Bellairs Storage Client" in
182
+
let info = Cmd.info "bellairs" ~doc in
193
+
let () = exit @@ Eio_main.run @@ fun env -> Cmd.eval (main_cmd env)