~/bend-docscommunity

src/argv.bend source

src/argv.bend on the hub · documented module

# src/argv: what `run`, `exec` and `start` do with an argv. `run.plan` decides# whether it can reach its program whole, and hands the effect `wire(argv)`# only then; `run.with` and `start.with` perform the plan with an effect given# as a parameter, so a refused plan can be seen to call none. `cmd` is the# newline wire ez's `pass` effect reads.import Base# the arguments joined on newlines, which is the wire ez's `pass` effect# reads. snap's own effects are handed `wire` and `par.plan`, since an# argument may hold a newline.def cmd(argv: List<&2, String>) -> String:  String.join(argv, "\n")# the arguments joined on newlines; the same as `cmd`def line(argv: List<&2, String>) -> String:  cmd(argv)# whether a string holds no copy of a chardef free_of(text: String, +sep: Char) -> Bool:  match text:    case SNil{}:      True{}    case SCon{ch, tail}:      rest = free_of(tail, sep)      Bool.and(Bool.not(Char.is_eq(ch, sep)), rest)# whether no string of a list holds a copy of a chardef free_of.all(ps: List<&2, String>, +sep: Char) -> Bool:  match ps:    case []:      True{}    case pc <> pt:      rest = free_of.all(pt, sep)      Bool.and(free_of(pc, sep), rest)# whether an argv can reach its program whole: it names a program, and no# argument holds NUL, which separates them on the wire and which no program# could be handed inside an argument anywaydef accepts(argv: List<&2, String>) -> Bool:  match argv:    case []:      False{}    case +prog <> +args:      Bool.and(Bool.not(String.is_empty(prog)), free_of.all(prog <> args, '\0'))# the arguments as the effects want them: joined on NUL, the one char no# argument can hold, so each is split back out wholedef wire(argv: List<&2, String>) -> String:  String.join(argv, "\0")# what a call does with its argv: refuse it, or hand the effect this wiretype Step is Data:  Refused{}  Run{wire: String}# an argv accepted is run; any other is refuseddef run.plan.of(ok: Bool, argv: List<&2, String>) -> Step:  match ok:    case True{}:      Run{wire(argv)}    case False{}:      Refused{}# what `run`, `exec` and `start` do with an argv. It decides everything: the# effect is called only with the wire of an argv this accepts.def run.plan(+argv: List<&2, String>) -> Step:  run.plan.of(accepts(argv), argv)# a step performed by an effect that waits: a refused argv answers as a# program that could not be started, and the effect is never calleddef run.with(eff: String -> IO(String), step: Step) -> IO(String):  match step:    case Refused{}:      IO.pure(String, "127\n")    case Run{w}:      eff(w)# a step performed by an effect that does not wait: a refused argv answers# as a program that could not be started, and the effect is never calleddef start.with(eff: String -> IO(String), step: Step) -> IO(String):  match step:    case Refused{}:      IO.pure(String, "0")    case Run{w}:      eff(w)