main.bend

cswap-bend-cli@0.1.0.0 · 53 lines · 8 definitions

1import Base
2import cswap-bend-cli@0.1.0.0/exec.bend as Exec
3import cswap-bend-cli@0.1.0.0/cmd.bend as Cmd
4import cswap-bend-cli@0.1.0.0/server.bend as Server
5import cswap-bend-cli@0.1.0.0/srvargs.bend as Sa
6
7# The cswap-bend program: run the command line, print its output, exit with its code.
8# `rpc` and `serve` are the two verbs that do not return a single answer: they
9# read requests and write responses until their input or a signal ends them.
10
11def write_err.m(c: Bool, +text: String) -> IO(Unit):
12  match c:
13    case True{}:
14      IO.pure(Unit, Unit{})
15    case False{}:
16      IO.print_err(String.trim_end(text))
17
18def write_err(+text: String) -> IO(Unit):
19  write_err.m(String.is_empty(text), text)
20def finish(o: Cmd.Out) -> IO(Unit):
21  match o:
22    case Cmd.Out{code, out, err}:
23      IO.bind(Unit, Unit, IO.write(out), u => IO.bind(Unit, Unit, write_err(err), v => IO.exit(code)))
24
25def run_plan(p: Sa.Plan) -> IO(Cmd.Out):
26  match p:
27    case Sa.PRpc{fmt}:
28      Server.rpc(fmt)
29    case Sa.PServe{path, fmt}:
30      Server.serve(path, fmt)
31    case Sa.PBad{msg}:
32      IO.pure(Cmd.Out, Cmd.Out{2, "", "usage: cswap <command> [args] [options]\ncswap: error: " ++ msg ++ "\n"})
33
34def route3(is_srv: Bool, +h: String, +t: List<&2, String>, +args: List<&2, String>) -> IO(Cmd.Out):
35  match is_srv:
36    case True{}:
37      run_plan(Sa.plan(h, t))
38    case False{}:
39      Exec.exec_line(args, None{})
40
41def route2(+args: List<&2, String>) -> IO(Cmd.Out):
42  match args:
43    case Nil{}:
44      Exec.exec_line(args, None{})
45    case Con{h, t}:
46      route3(String.eq(h, "rpc") || String.eq(h, "serve"), h, t, Con{h, t})
47
48# The command for `IO.args` (its head is the program name).
49def run(ts: List<String>) -> IO(Cmd.Out):
50  route2(Exec.tail_of(ts))
51
52def main() -> IO(Unit):
53  IO.bind(List<String>, Unit, IO.args(), ts => IO.bind(Cmd.Out, Unit, run(ts), finish))