srvargs.bend
cswap-bend-cli@0.1.0.0 · 104 lines · 17 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/fmt/out.bend as O
3
4
5
6
7type Plan is Data:
8 PRpc{fmt: O.Fmt}
9 PServe{path: String, fmt: O.Fmt}
10 PBad{msg: String}
11
12type A is Data:
13 A{fmt: Maybe<&2, String>, socket: Maybe<&2, String>, err: String, want: String}
14
15def err(+a: A, msg: String) -> A:
16 match a:
17 case A{fmt, socket, e, w}:
18 A{fmt, socket, Bool.pick(String, String.is_empty(e), msg, e), ""}
19
20def got(+a: A, +v: String) -> A:
21 match a:
22 case A{fmt, socket, e, w}:
23 Bool.pick(A, String.eq(w, "--format"), A{Some{v}, socket, e, ""}, A{fmt, Some{v}, e, ""})
24
25def want(+a: A, +flag: String) -> A:
26 match a:
27 case A{fmt, socket, e, w}:
28 A{fmt, socket, e, flag}
29
30def pending(+a: A) -> Bool:
31 match a:
32 case A{fmt, socket, e, w}:
33 Bool.not(String.is_empty(w))
34
35def sel.a(c: Bool, +x: A, +y: A) -> A:
36 match c:
37 case True{}:
38 x
39 case False{}:
40 y
41
42def free(+h: String, +a: A) -> A:
43 sel.a(String.eq(h, "--format") || String.eq(h, "--socket"), want(a, h),
44 sel.a(String.starts_with(h, "--format="), got(want(a, "--format"), String.drop(h, 9n)),
45 sel.a(String.starts_with(h, "--socket="), got(want(a, "--socket"), String.drop(h, 9n)),
46 err(a, "unrecognized arguments: " ++ h))))
47
48def step(+h: String, +a: A) -> A:
49 sel.a(pending(a), got(a, h), free(h, a))
50
51def go(args: List<&2, String>, +a: A) -> A:
52 match args:
53 case Nil{}:
54 a
55 case Con{h, t}:
56 go(t, step(h, a))
57
58def end(+a: A) -> A:
59 match a:
60 case A{fmt, socket, e, w}:
61 Bool.pick(A, String.is_empty(w), a, err(a, "argument " ++ w ++ ": expected one argument"))
62
63def fmt_of2(m: Maybe<&2, O.Fmt>, +name: String) -> Result<&2, &2, String, O.Fmt>:
64 match m:
65 case Some{O.FText{}}:
66 Fail{"argument --format: invalid choice: '" ++ name ++ "' (choose from 'json', 'toon', 'yaml')"}
67 case Some{O.FCsv{}}:
68 Fail{"argument --format: invalid choice: '" ++ name ++ "' (choose from 'json', 'toon', 'yaml')"}
69 case Some{f}:
70 Done{f}
71 case None{}:
72 Fail{"argument --format: invalid choice: '" ++ name ++ "' (choose from 'json', 'toon', 'yaml')"}
73
74def fmt_of(m: Maybe<&2, String>) -> Result<&2, &2, String, O.Fmt>:
75 match m:
76 case None{}:
77 Done{O.FJson{}}
78 case Some{+n}:
79 fmt_of2(O.of_name(n), n)
80
81def plan4(serve: Bool, +f: O.Fmt, socket: Maybe<&2, String>) -> Plan:
82 match serve socket:
83 case True{} Some{p}:
84 PServe{p, f}
85 case True{} None{}:
86 PBad{"the following arguments are required: --socket"}
87 case False{} _:
88 PRpc{f}
89
90def plan3(+verb: String, r: Result<&2, &2, String, O.Fmt>, socket: Maybe<&2, String>) -> Plan:
91 match r:
92 case Fail{m}:
93 PBad{m}
94 case Done{f}:
95 plan4(String.eq(verb, "serve"), f, socket)
96
97def plan2(+verb: String, +a: A) -> Plan:
98 match a:
99 case A{fmt, socket, e, w}:
100 Bool.pick(Plan, String.is_empty(e), plan3(verb, fmt_of(fmt), socket), PBad{e})
101
102
103def plan(+verb: String, args: List<&2, String>) -> Plan:
104 plan2(verb, end(go(args, A{None{}, None{}, "", ""})))