1 import Base 2 import ./json.bend as Json 3 4 # What a CLI command answers: the exit code and the text for each stream. 5 # `out` and `err` carry their own newlines. main prints them and exits. 6 7 type Out is Data: 8 Out{code: U32, out: String, err: String} 9 10 def ok(text: String) -> Out: 11 Out{0, text ++ "\n", ""} 12 13 def silent() -> Out: 14 Out{0, "", ""} 15 16 # A handled error, text mode: `Error: ` on stderr, exit 1. 17 def fail(msg: String) -> Out: 18 Out{1, "", "Error: " ++ msg ++ "\n"} 19 20 # A usage error (argparse): the message on stderr, exit 2. 21 def usage(msg: String) -> Out: 22 Out{2, "", "cswap: error: " ++ msg ++ "\n"} 23 24 # The --json error envelope: stdout, exit 1. 25 def json_fail(kind: String, msg: String) -> Out: 26 Out{1, Json.emit_pretty(Json.of_pairs([ 27 ("schemaVersion", Json.JNum{"1"}), 28 ("error", Json.of_pairs([("type", Json.JStr{kind}), ("message", Json.JStr{msg})]))])) ++ "\n", ""} 29 30 # `json` picks the envelope or the text error. 31 def failed(json: Bool, kind: String, msg: String) -> Out: 32 match json: 33 case True{}: 34 json_fail(kind, msg) 35 case False{}: 36 fail(msg) 37 38 # A JSON document on stdout, indent=2. 39 def doc(j: Json.Json) -> Out: 40 Out{0, Json.emit_pretty(j) ++ "\n", ""}