···
+
module API = Schema.Storage.MakeRPC (Capnp_rpc)
+
with type file = API.Client.File.t Capability.t
+
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"
let open API.Client.Directory.List in
let request = Capability.Request.create_no_args () in
···
let entries = Results.entries_get_list results in
+
let open API.Client.Directory.Create in
+
let request, params = Capability.Request.create Params.init_pointer in
+
Params.name_set params name;
+
let results = Capability.call_for_value_exn t method_id request in
+
match Results.file_get results with
+
| None -> failwith "create: no file returned"
+
let open API.Client.Directory.Open in
+
let request, params = Capability.Request.create Params.init_pointer in
+
Params.name_set params name;
+
let results = Capability.call_for_value_exn t method_id request in
+
match Results.file_get results with
+
| None -> failwith "open: no file returned"
+
let open API.Client.Directory.Delete in
+
let request, params = Capability.Request.create Params.init_pointer in
+
Params.name_set params name;
+
let _ = Capability.call_for_value_exn t method_id request in
+
let open API.Client.File.Size in
+
let request = Capability.Request.create_no_args () in
+
let results = Capability.call_for_value_exn t method_id request in
+
Stdint.Int64.of_uint64 (Results.size_get results)
+
let open API.Client.File.Read in
+
let request, params = Capability.Request.create Params.init_pointer in
+
| Some off -> Params.off_set params (Stdint.Int64.to_uint64 off)
+
| Some len -> Params.len_set params (Stdint.Int64.to_uint64 len)
+
let results = Capability.call_for_value_exn t method_id request in
+
Results.data_get results
+
let connect net uri f =
let client_vat = Capnp_rpc_unix.client_only_vat ~sw net in
+
let client = Capnp_rpc_unix.Vat.import_exn client_vat uri in
+
Capnp_rpc_unix.with_cap_exn client f
+
let pp_file ppf file = Fmt.pf ppf "[%a]" Capnp_rpc.Capability.pp file
+
let pp_entry ppf entry =
+
Fmt.pf ppf "%s:%a" entry.Storage.name pp_file entry.file
+
connect net uri @@ fun dir ->
+
let entries = Storage.list dir in
+
Printf.printf "total %d:\n" (List.length entries);
+
List.iter (Fmt.pr "- %a\n" pp_entry) entries;
+
let create net uri name =
+
connect net uri @@ fun dir ->
+
let file = Storage.create dir name in
+
Fmt.pr "Created file '%s': %a\n" name pp_file file
+
let open_file net uri name =
+
connect net uri @@ fun dir ->
+
let file = Storage.open_ dir name in
+
Fmt.pr "Opened file '%s': %a\n" name pp_file file
+
let delete net uri name =
+
connect net uri @@ fun dir ->
+
Storage.delete dir name;
+
Fmt.pr "Deleted file '%s'\n" name
+
let size net uri name =
+
connect net uri @@ fun dir ->
+
let file = Storage.open_ dir name in
+
let size = Storage.size file in
+
Fmt.pr "Size of '%s': %Ld bytes\n" name size
+
let read net addr name offset length =
+
connect net addr @@ fun dir ->
+
let file = Storage.open_ dir name in
+
let data = Storage.read ?off:offset ?len:length file in
+
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)
+
let i = Arg.info [] ~docv:"NAME" ~doc:"Name of the file" in
+
Arg.(required @@ pos 1 (some string) None i)
+
Arg.info [ "o"; "offset" ] ~docv:"OFFSET"
+
~doc:"Offset from where to start reading (default: 0)"
+
Arg.(value @@ opt (some int64) None i)
+
Arg.info [ "l"; "length" ] ~docv:"LENGTH"
+
~doc:"Number of bytes to read (default: all)"
+
Arg.(value @@ opt (some int64) None i)
+
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)
+
let doc = "Create a new file" in
+
let info = Cmd.info "create" ~doc in
+
Cmd.v info Term.(const (create env#net) $ connect_addr $ name_arg)
+
let doc = "Open an existing file and show its ID" in
+
let info = Cmd.info "open" ~doc in
+
Cmd.v info Term.(const (open_file env#net) $ connect_addr $ name_arg)
+
let doc = "Delete a file" in
+
let info = Cmd.info "delete" ~doc in
+
Cmd.v info Term.(const (delete env#net) $ connect_addr $ name_arg)
+
let doc = "Get the size of a file" in
+
let info = Cmd.info "size" ~doc in
+
Cmd.v info Term.(const (size env#net) $ connect_addr $ name_arg)
+
let doc = "Read the contents of a file" in
+
let info = Cmd.info "read" ~doc in
+
const (read env#net) $ connect_addr $ name_arg $ offset_arg $ length_arg)
+
let doc = "Bellairs Storage Client" in
+
let info = Cmd.info "bellairs" ~doc in
+
let () = exit @@ Eio_main.run @@ fun env -> Cmd.eval (main_cmd env)