1 import Base 2 import ./exec.bend as Exec 3 import ./cmd.bend as Cmd 4 import ./server.bend as Server 5 import ./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 11 def 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 18 def write_err(+text: String) -> IO(Unit): 19 write_err.m(String.is_empty(text), text) 20 def 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 25 def 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 [args] [options]\ncswap: error: " ++ msg ++ "\n"}) 33 34 def 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 41 def 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). 49 def run(ts: List) -> IO(Cmd.Out): 50 route2(Exec.tail_of(ts)) 51 52 def main() -> IO(Unit): 53 IO.bind(List, Unit, IO.args(), ts => IO.bind(Cmd.Out, Unit, run(ts), finish))