Dead simple data-oriented argument parsing for Nim.
nimble install easyargs
Most other Nim opt parsers handle the complex cases. But 80% of the use cases for CLI parsing are covered by 20% of the opt parser features. Within that 80%, all we need to know is:
- If our command or subcommand was a given thing.
- What a positional argument was.
- What an option with input was, with a default fallback.
- If a flag was present.
I wrote this because I didn't want to generate massive new code paths at compile time, I wanted to write my own docstrings, and I wanted to use a simple data-oriented API to evaluate inputs. Starting from the foundation of std/parseopt, I simplified the basic use cases into 7 tiny procs in 50 lines of code.
With easyargs, you can write a data-oriented cascading argument parser. You can query what was present, and then pass that data to the next procs in the pipeline. Conveniently, easyargs exports std/parseopt so you don't need to import it to call initOptParser().
getOption(oparser: var OptParser, name: string, default: string, short: string = ""): string
## For options which can be long and optionally short.
getOptionShort(oparser: var OptParser, short: string, default: string): string
## For short-only options.
getFlag(oparser: var OptParser, name: string, short: string = ""): bool
## For flags which can be long and optionally short.
getFlagShort(oparser: var OptParser, short: string): bool
## For short-only flags.
getArgAtIndex(oparser: var OptParser, index: int): string
## For positional arguments.
commandWas(oparser: var OptParser, cmd: string): bool
## Queries if the first argument was the given string.
subcommandWas(oparser: var OptParser, cmd: string): bool
## Queries if the second argument was the given string.import std/strformat
import std/strutils
import easyargs
var cli = initOptParser()
echo &"""Command was `foo`?: {cli.commandWas("foo")}"""
echo &"""Subcommand was `bar`?: {cli.subcommandWas("bar")}"""
echo &"""Option `switch` was: {cli.getOption("switch", "none", short = "s")}"""
echo &"""Option `quality` was: {cli.getOption("quality", "100", short = "q").parseInt()}"""
echo &"""Flag `convert` was: {cli.getFlag("convert", short = "c")}"""
echo &"""Option `t` was: {cli.getOptionShort("t", "none")}"""
echo &"""Flag a was: {cli.getFlagShort("a")}"""
echo &"""Flag e was: {cli.getFlagShort("e")}"""
echo &"""Flag i was: {cli.getFlagShort("i")}"""
echo &"""Flag o was: {cli.getFlagShort("o")}"""
echo &"""Flag u was: {cli.getFlagShort("u")}"""import std/strutils
import easyargs
<...>
proc main =
var cli = initOptParser()
if cli.commandWas("ship"):
if cli.subcommandWas("move"):
shipMove(
x = cli.get_option_short("x", "-1").parseInt(),
y = cli.get_option_short("y", "-1").parseInt()
)
elif cli.subcommandWas("turn"):
shipTurn(
angle = cli.getOption("angle", "-1", short = "a").parseInt(),
counterclockwise = cli.getFlag("counterclockwise", short = "c")
)
elif cli.commandWas("new"):
makeShip(
name = cli.getOption("name", "Boaty McBoatface", short = "n")
)
elif cli.getFlag("help", short = "h"):
echo helpString
elif cli.getFlag("version", short = "v"):
echo versionString
else:
echo usageString