Rill v0.13 Reference

Standard library · The command line

cli/args

Imported as import "cli/args" as args, its names are then args.…. Every signature below is the one the checker infers.

Command-line arguments: what a program takes, said once, and then parsed, checked and explained from that one saying.

--port 80, --port=80 and -p 80 all set port; --verbose and -v set a switch; -- ends the options and everything after it is a slot. --help and -h answer with the usage text as the error, so a program that prints why has help for free.

spec = args.tool("serve", "serve a directory over HTTP")
  |> args.switch("verbose", "v", "say what is served")
  |> args.valued("port", "p", "PORT", "8080", "the port to listen on")
  |> args.slot("dir", "the directory to serve", true)
got = args.parse(spec, Cons("serve", Cons("-v", Cons("--port=9000", Cons("www", Nil)))))?
args.value(got, "port")      # => 9000
args.on(got, "verbose")      # => true
args.slots(got)              # => Cons(www, Nil)
res_map(args.parse(spec, Cons("serve", Nil)), \g -> 0)   # => Err(missing <dir>\nusage: serve [options] <dir>\n  serve a directory over HTTP\n\n  -v, --verbose    say what is served\n  -p, --port PORT  the port to listen on (default 8080)\n  <dir>            the directory to serve\n  -h, --help       this)

Types

Item

  • Switch(long: Str, short: Str, help: Str)
  • Valued(long: Str, short: Str, meta: Str, default: Str, help: Str)
  • Slot(name: Str, help: Str, required: Bool)

Spec

  • Spec(name: Str, about: Str, items: List(Item))

Got

What a parse found: the switches given, the values (given or defaulted), and the slots in order.

  • Got(switches: Map(Str, Int), values: Map(Str, Str), slots: List(Str))

Functions

fn tool(name: Str, about: Str) -> Spec

args.usage(args.tool("hello", "greet someone"))   # => usage: hello [options]\n  greet someone\n\n  -h, --help  this

fn switch(s: Spec, long: Str, short: Str, help: Str) -> Spec

spec = args.tool("t", "") |> args.switch("quiet", "q", "say nothing")
args.on(args.parse(spec, Cons("t", Cons("-q", Nil)))?, "quiet")   # => true
args.on(args.parse(spec, Cons("t", Nil))?, "quiet")               # => false

fn valued(s: Spec, long: Str, short: Str, meta: Str, default: Str, help: Str) -> Spec

spec = args.tool("t", "") |> args.valued("name", "n", "NAME", "world", "whom to greet")
args.value(args.parse(spec, Cons("t", Nil))?, "name")                        # => world
args.value(args.parse(spec, Cons("t", Cons("-n", Cons("ada", Nil))))?, "name")   # => ada

fn slot(s: Spec, name: Str, help: Str, required: Bool) -> Spec

spec = args.tool("t", "") |> args.slot("file", "the input", false)
args.slots(args.parse(spec, Cons("t", Cons("a.txt", Nil)))?)   # => Cons(a.txt, Nil)
args.slots(args.parse(spec, Cons("t", Nil))?)                    # => Nil

fn on(g: Got, long: Str) -> Bool

spec = args.tool("t", "") |> args.switch("all", "a", "everything")
args.on(args.parse(spec, Cons("t", Cons("--all", Nil)))?, "all")   # => true

fn value(g: Got, long: Str) -> Str

The value given for long, or its default.

spec = args.tool("t", "") |> args.valued("port", "p", "PORT", "80", "")
args.value(args.parse(spec, Cons("t", Cons("--port", Cons("8080", Nil))))?, "port")   # => 8080

fn slots(g: Got) -> List(Str)

spec = args.tool("t", "") |> args.slot("x", "", false) |> args.slot("y", "", false)
args.slots(args.parse(spec, Cons("t", Cons("--", Cons("-not-a-flag", Cons("b", Nil)))))?)   # => Cons(-not-a-flag, Cons(b, Nil))

fn parse(s: Spec, argv: List(Str)) -> Result(Got, Str)

The program name is args()'s first, and is skipped.

spec = args.tool("t", "") |> args.switch("v", "v", "")
res_map(args.parse(spec, Cons("t", Cons("--nope", Nil))), \g -> 0)   # => Err(`--nope` is not an option of t\nusage: t [options]\n\n  -v, --v     \n  -h, --help  this)
res_map(args.parse(spec, Cons("t", Cons("--help", Nil))), \g -> 0)   # => Err(usage: t [options]\n\n  -v, --v     \n  -h, --help  this)

fn usage(s: Spec) -> Str

The tool's line, then one line per item, aligned.

spec = args.tool("cp", "copy a file") |> args.slot("from", "the source", true) |> args.slot("to", "the destination", true)
args.usage(spec)   # => usage: cp [options] <from> <to>\n  copy a file\n\n  <from>      the source\n  <to>        the destination\n  -h, --help  this

Tests

  • test_options_and_slots
  • test_errors_and_help