2 unstable releases

0.2.0 Jun 21, 2023
0.1.0 Jun 4, 2023

#36 in #command-arguments

29 downloads per month

MIT license

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 Results and Options 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

No runtime deps