Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/docopt/docopt.rs

Docopt for Rust (command line argument parser).
https://github.com/docopt/docopt.rs

Last synced: about 2 months ago
JSON representation

Docopt for Rust (command line argument parser).

Awesome Lists containing this project

README

        

# THIS CRATE IS UNMAINTAINED

This crate is unlikely to see significant future evolution. The primary reason
to choose this crate for a new project is if you're specifically interested in
using [docopt](http://docopt.org/) syntax for your project. However, the wider
docopt project is mostly unmaintained at this point.

Consider using [clap](http://docs.rs/clap/) or possibly
[structopt](http://docs.rs/structopt/) instead.

Note that this crate has some significant bugs. The two biggest ones are the
lack of `OsStr` support and some severe performance problems in not-uncommon
edge cases.

docopt
======

Docopt for Rust with automatic type based decoding (i.e., data validation).
This implementation conforms to the
[official description of Docopt](http://docopt.org/) and
[passes its test suite](https://github.com/docopt/docopt/pull/201).

[![Build status](https://api.travis-ci.org/docopt/docopt.rs.svg)](https://travis-ci.org/docopt/docopt.rs)
[![](http://meritbadge.herokuapp.com/docopt)](https://crates.io/crates/docopt)

Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).

### Documentation

https://docs.rs/docopt

### Installation

This crate is fully compatible with Cargo. Just add it to your `Cargo.toml`:

```toml
[dependencies]
docopt = "1"
serde = { version = "1", features = ["derive"] }
```

### Quick example

Here is a full working example. Notice that you can specify the types of each
of the named values in the Docopt usage string. Values will be automatically
converted to those types (or an error will be reported).

```rust
use docopt::Docopt;
use serde::Deserialize;

const USAGE: &'static str = "
Naval Fate.

Usage:
naval_fate.py ship new ...
naval_fate.py ship move [--speed=]
naval_fate.py ship shoot
naval_fate.py mine (set|remove) [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version

Options:
-h --help Show this screen.
--version Show version.
--speed= Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
";

#[derive(Debug, Deserialize)]
struct Args {
flag_speed: isize,
flag_drifting: bool,
arg_name: Vec,
arg_x: Option,
arg_y: Option,
cmd_ship: bool,
cmd_mine: bool,
}

fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);
}
```

### Struct field name mapping

The field names of the struct map like this:

```
-g => flag_g
--group => flag_group
--group => flag_group
FILE => arg_FILE
=> arg_file
build => cmd_build
```

### Traditional Docopt API

The reference implementation of Docopt returns a Python dictionary with names
like `` or `--flag`. If you prefer this access pattern, then you can use
`docopt::ArgvMap`. The disadvantage is that you have to do all of your type
conversion manually. Here's the canonical Docopt example with a hash table:

```rust
use docopt::Docopt;

const USAGE: &'static str = "
Naval Fate.

Usage:
naval_fate.py ship new ...
naval_fate.py ship move [--speed=]
naval_fate.py ship shoot
naval_fate.py mine (set|remove) [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version

Options:
-h --help Show this screen.
--version Show version.
--speed= Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
";

fn main() {
let args = Docopt::new(USAGE)
.and_then(|dopt| dopt.parse())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);

// You can conveniently access values with `get_{bool,count,str,vec}`
// functions. If the key doesn't exist (or if, e.g., you use `get_str` on
// a switch), then a sensible default value is returned.
println!("\nSome values:");
println!(" Speed: {}", args.get_str("--speed"));
println!(" Drifting? {}", args.get_bool("--drifting"));
println!(" Names: {:?}", args.get_vec(""));
}
```

### Tab completion support

This particular implementation bundles a command called `docopt-wordlist` that
can be used to automate tab completion. This repository also collects some
basic completion support for various shells (currently only bash) in the
`completions` directory.

You can use them to setup tab completion on your system. It should work with
any program that uses Docopt (or rather, any program that outputs usage
messages that look like Docopt). For example, to get tab completion support for
Cargo, you'll have to install `docopt-wordlist` and add some voodoo to your
`$HOME/.bash_completion` file (this may vary for other shells).

Here it is step by step:

```bash
# Download and build `docopt-wordlist` (as part of the Docopt package)
$ git clone git://github.com/docopt/docopt.rs
$ cd docopt.rs
$ cargo build --release

# Now setup tab completion (for bash)
$ echo "DOCOPT_WORDLIST_BIN=\"$(pwd)/target/release/docopt-wordlist\"" >> $HOME/.bash_completion
$ echo "source \"$(pwd)/completions/docopt-wordlist.bash\"" >> $HOME/.bash_completion
$ echo "complete -F _docopt_wordlist_commands cargo" >> $HOME/.bash_completion
```

My [CSV toolkit](https://github.com/BurntSushi/xsv) is supported too:

```bash
# shameless plug...
$ echo "complete -F _docopt_wordlist_commands xsv" >> $HOME/.bash_completion
```

Note that this is emphatically a first pass. There are several improvements
that I'd like to make:

1. Take context into account when completing. For example, it should be
possible to only show completions that can lead to a valid Docopt match.
This may be hard. (i.e., It may require restructuring Docopt's internals.)
2. Support more shells. (I'll happily accept pull requests on this one. I doubt
I'll venture outside of bash any time soon.)
3. Make tab completion support more seamless. The way it works right now is
pretty hacky by intermingling file/directory completion.