• This repository has been archived on 14/Sep/2023
  • Stars
    star
    754
  • Rank 57,950 (Top 2 %)
  • Language
    Rust
  • License
    The Unlicense
  • Created almost 10 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Docopt for Rust (command line argument parser).

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 syntax for your project. However, the wider docopt project is mostly unmaintained at this point.

Consider using clap or possibly 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 and passes its test suite.

Build status

Dual-licensed under MIT or the UNLICENSE.

Documentation

https://docs.rs/docopt

Installation

This crate is fully compatible with Cargo. Just add it to your Cargo.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).

use docopt::Docopt;
use serde::Deserialize;

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

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

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  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<String>,
    arg_x: Option<i32>,
    arg_y: Option<i32>,
    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 <arg> => flag_group
FILE          => arg_FILE
<file>        => arg_file
build         => cmd_build

Traditional Docopt API

The reference implementation of Docopt returns a Python dictionary with names like <arg> 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:

use docopt::Docopt;

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

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

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  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("<name>"));
}

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:

# 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 is supported too:

# 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.

More Repositories

1

docopt

This project is no longer maintained. Please see https://github.com/jazzband/docopt-ng
Python
7,893
star
2

docopt.go

A command-line arguments parser that will make you smile.
Go
1,422
star
3

docopt.cpp

C++11 port of docopt
C++
1,028
star
4

docopts

Shell interpreter for docopt, the command-line interface description language.
Shell
489
star
5

docopt.rb

Parse command line arguments from nothing more than a usage message
Ruby
461
star
6

docopt.net

Port of docopt to .net
C#
348
star
7

docopt.c

C-code generator for docopt language.
Python
316
star
8

docopt.php

Command line argument parser
PHP
298
star
9

docopt.R

Command-line interface description language for R (http://docopt.org)
R
205
star
10

docopt.nim

Command line arguments parser that will make you smile (port of docopt to Nim)
Nim
202
star
11

docopt.java

Java port of docopt
Java
156
star
12

docopt.coffee

docopt - A command line option parser that will make you smile.
CoffeeScript
148
star
13

docopt.hs

A command-line interface description language and parser that will make you smile
Haskell
118
star
14

DocOpt.jl

command line arguments parser
Julia
88
star
15

docopt.clj

Clojure implementation of the docopt language.
Clojure
65
star
16

try.docopt.org

Try out docopt in browser (Flask app running on Heroku)
CSS
61
star
17

docopt.swift

A command-line interface description language and parser that will make you smile http://docopt.org/
Swift
52
star
18

docopt.lua

Lua
37
star
19

docopt.scala

Scala implementation of docopt language
Scala
37
star
20

docopt.fs

Docopt for F#
F#
34
star
21

docopt.d

D
30
star
22

docopt.org

The website
Tcl
25
star
23

docopt.tcl

docopt.org for TCL
Tcl
4
star
24

challenge.docopt.org

Challenge docopt site
Python
3
star
25

docopt.rs-old

New Rust port is here:
Rust
2
star