2 unstable releases
0.2.0 | Jun 21, 2023 |
---|---|
0.1.0 | Jun 4, 2023 |
#36 in #command-arguments
29 downloads per month
18KB
228 lines
bind-args
Binding arguments provided on the command line to Rust types
lib.rs
:
An unorthodox approach to command line parsing
Examples
Make sure to handle and Result
s and Option
s if you are writing code you care about
use bind_args::BoundArgs;
let cmd_line = ["add", "=origin", "=https://example.org/repo.git", "--log"];
// Alternatively, you could do: let args = BoundArgs::try_from(std::env::args()).unwrap();
let args = BoundArgs::new(cmd_line).unwrap();
let add_command = args.with_command("add").unwrap();
assert_eq!(add_command.argument(0), Some("origin"));
assert_eq!(add_command.argument(1), Some("https://example.org/repo.git"));
assert_eq!(add_command.flag("log"), true);
Let's define some terms
Command Line
A "command line" (for the purposes of this crate) is the input to your executable when you call it from your shell.
In this this example:
git commit -m "a message"
commit -m "message"
is the command line. The quotes you add around a message
are a shell
construct to make it clear that a message
is one input to the executable instead of two. What
the executable actually sees is:
["commit", "-m", "a message"]
If those quotes were not there, the executable would see this:
["commit", "-m", "a", "message"]
Which might change its behavior!
Note: From now on, I'll be referring to individual contents of this array as command line "items"
Option
An option is a command line item that has a name and value. A long option is
prefixed with --
and can have whatever name you want. A short option is prefixed with -
and must be one character long.
An equals sign (=
) MUST appear between the option name and value. Providing the same option
multiple times concatenates the values into an array.
Examples of options:
["--debug=info"]
["--option=one", "--option=two", "--option=three"]
["-v=hello world"]
Flag
A flag is an option without a value. It's absence denotes a false
value and its presence a
true
value. Any subsequent instances of the same flag do nothing.
Examples of flags:
["--verbose"]
["-h"]
Argument
An argument is an option without a name. As such it's meaning is tied only to its position on
the command line. Arguments must be prefixed with an equals sign (=
).
Examples of arguments:
["=remote"]
["=argument with space"]
Command
Anything that is not an option, flag or argument is considered a command. Every executable has at least one command, the executable name itself!. Packing more functionality into your executable can be useful though. You would define sub-commands that correspond for the groups of functionality your executable can do.
Examples of commands:
["remote", "add"]
Any arguments, flags and options that appear after a command are scoped to that command. Meaning this crate differentiates between:
git --help commit
and
git commit --help
Rationale for the weird/new argument syntax:
Take the following command line for example:
$ git remote add origin https://example.org --fetch
Without having a specification for git
beforehand, it is impossible to know if remote
,
add
and origin
are commands or arguments. We already have a way to differentiate flags and
options from the rest, so why not do the same for arguments?
If git
was written with this library's rules in mind, that command line would look like this:
$ git remote add =origin =https://example.org --fetch