aboutsummaryrefslogtreecommitdiff
path: root/argparse/README.rst
blob: 8a3fca0658559ecbf49a80137743c57bee886fb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
========
Argparse
========

The ``rust-argparse`` is command-line parsing module for rust. It's inspired
by python's ``argparse`` module.

Features:

* Supports standard (GNU) option conventions
* Properly typed values
* Automatically generated help and usage messages

Importing
=========
Edit your Cargo.toml to add ``rust-argparse`` to your project.

.. code-block:: rust

    [dependencies]
    argparse = "0.2.2"


Example
=======

The following code is a simple Rust program with command-line arguments:

.. code-block:: rust

    extern crate argparse;

    use argparse::{ArgumentParser, StoreTrue, Store};

    fn main() {
        let mut verbose = false;
        let mut name = "World".to_string();
        {  // this block limits scope of borrows by ap.refer() method
            let mut ap = ArgumentParser::new();
            ap.set_description("Greet somebody.");
            ap.refer(&mut verbose)
                .add_option(&["-v", "--verbose"], StoreTrue,
                "Be verbose");
            ap.refer(&mut name)
                .add_option(&["--name"], Store,
                "Name for the greeting");
            ap.parse_args_or_exit();
        }

        if verbose {
            println!("name is {}", name);
        }
        println!("Hello {}!", name);
    }

Assuming the Rust code above is saved into a file ``greeting.rs``, let's see
what we have now::

    $ rustc greeting.rs
    $ ./greeting -h
    Usage:
      ./greeting [OPTIONS]

    Greet somebody.

    Optional arguments:
      -h, --help  Show this help message and exit
      -v, --verbose
                 Be verbose
      --name NAME Name for the greeting
    $ ./greeting
    Hello World!
    $ ./greeting --name Bob
    Hello Bob!
    $ ./greeting -v --name Alice
    name is Alice
    Hello Alice!


Basic Workflow
==============


Create ArgumentParser
---------------------

The argument parser is created empty and is built incrementally. So we create
a mutable variable::

    extern crate argparse;
    use argparse::ArgumentParser;

    let mut parser = ArgumentParser::new();


Customize
---------

There are optional customization methods. The most important one is::

    parser.set_description("My command-line utility")

The descripion is rewrapped to fit 80 column string nicely. Just like option
descriptions.

Add Options
-----------

The ``refer`` method creates a cell variable, which the result will be written
to::

    let mut verbose = false;
    parser.refer(&mut verbose);

Next we add an options which control the variable:
For example::

    parser.refer(&mut verbose)
        .add_option(&["-v", "--verbose"], StoreTrue,
                    "Be verbose");

You may add multiple options for the same variable::

    parser.refer(&mut verbose)
        .add_option(&["-v", "--verbose"], StoreTrue,
                    "Be verbose")
        .add_option(&["-q", "--quiet"], StoreFalse,
                    "Be verbose");

Similarly positional arguments are added::

    let mut command = String;
    parser.refer(&mut command)
        .add_argument("command", Store,
                      "Command to run");



Organizing Options
------------------

It's often useful to organize options into some kind of structure. You can
easily borrow variables from the structure into option parser. For example::

    struct Options {
        verbose: bool,
    }
    ...
    let mut options = Options { verbose: false };
    parser.refer(&mut options.verbose)
        .add_option(&["-v"], StoreTrue,
                    "Be verbose");


Parsing Arguments
-----------------

All the complex work is done in ``parser.parse_args()``. But there is
a simpler option::

    parser.parse_args_or_exit()

In case you don't want argparse to exit itself, you might use the
``parse_args`` function directly::

    use std::process::exit;

    match parser.parse_args() {
        Ok(()) =>  {}
        Err(x) => {
            std::process::exit(x);
        }
    }


ArgumentParser Methods
======================

``parser.refer<T>(var: &mut T) -> Ref``
    Attach the variable to argument parser. The options are added to the
    returned ``Ref`` object and modify a variable passed to the method.

``parser.add_option(names: &[&str], action: TypedAction, help: &str)``
    Add a single option which has no parameters. Most options must be added
    by ``refer(..)`` and methods on ``Ref`` object (see below).

    Example::

        ap.add_option(&["-V", "--version"],
            Print(env!("CARGO_PKG_VERSION").to_string()), "Show version");

``parser.set_description(descr: &str)``
    Set description that is at the top of help message.

``parser.stop_on_first_argument(val: bool)``
    If called with ``true``, parser will stop searching for options when first
    non-option (the one doesn't start with ``-``) argument is encountered. This
    is useful if you want to parse following options with another argparser or
    external program.

``parser.silence_double_dash(val: bool)``
    If called with ``true`` (default), parser will not treat *first* double
    dash ``--`` as positional argument. Use ``false`` if you need to add some
    meaning to the ``--`` marker.

``parser.print_usage(name: &str, writer: &mut Write)``
    Prints usage string to stderr.

``parser.print_help(name: &str, writer: &mut Write)``
    Writes help to ``writer``, used by ``--help`` option internally.

``parser.parse_args()``
    Method that does all the dirty work. And returns ``Result``

``parser.parse_args_or_exit()``
    Method that does all the dirty work. And in case of failure just ``exit()``


Variable Reference Methods
==========================

The ``argparse::Ref`` object is returned from ``parser.refer()``.
The following methods are used to add and customize arguments:

``option.add_option(names: &[&str], action: TypedAction, help: &str)``
    Add an option. All items in names should be either in format ``-X`` or
    ``--long-option`` (i.e. one dash and one char or two dashes and long name).
    How this option will be interpreted and whether it will have an argument
    dependes on the action. See below list of actions.

``option.add_argument(name: &str, action: TypedAction, help: &str)``
    Add a positional argument

``option.metavar(var: &str)``
    A name of the argument in usage messages (for options having argument).

``option.envvar(var: &str)``
    A name of the environment variable to get option value from. The value
    would be parsed with ``FromStr::from_str``, just like an option having
    ``Store`` action.

``option.required()``
    The option or argument is required (it's optional by default). If multiple
    options or multiple arguments are defined for this reference at least one
    of them is required.


Actions
=======

The following actions are available out of the box. They may be used in either
``add_option`` or ``add_argument``:

``Store``
    An option has single argument. Stores a value from command-line in a
    variable. Any type that has the ``FromStr`` and ``Clone`` traits implemented
    may be used.

``StoreOption``
    As ``Store``, but wrap value with ``Some`` for use with ``Option``. For
    example:

        let mut x: Option<i32> = None;
        ap.refer(&mut x).add_option(&["-x"], StoreOption, "Set var x");

``StoreConst(value)``
    An option has no arguments. Store a hard-coded ``value`` into variable,
    when specified. Any type with the ``Clone`` trait implemented may be used.

``PushConst(value)``
    An option has no arguments. Push a hard-coded ``value`` into variable,
    when specified. Any type which has the ``Clone`` type implemented may be
    used. Option might used for a list of operations to perform, when ``required``
    is set for this variable, at least one operation is required.

``StoreTrue``
    Stores boolean ``true`` value in a variable.
    (shortcut for ``StoreConst(true)``)

``StoreFalse``
    Stores boolean ``false`` value in a variable.
    (shortcut for ``StoreConst(false)``)


``IncrBy(num)``
    An option has no arguments. Increments the value stored in a variable by a
    value ``num``. Any type which has the ``Add`` and ``Clone`` traits may be used.

``DecrBy(nym)``
    Decrements the value stored in a variable by a value ``num``. Any type
    which has the ``Add`` and ``Clone`` traits may be used.

``Collect``
    When used for an ``--option``, requires single argument. When used for a
    positional argument consumes all remaining arguments. Parsed options are
    added to the list. I.e. a ``Collect`` action requires a
    ``Vec<int>`` variable. Parses arguments using ``FromStr`` trait.

``List``
    When used for positional argument, works the same as ``List``. When used
    as an option, consumes all remaining arguments.

    Note the usage of ``List`` is strongly discouraged, because of complex
    rules below. Use ``Collect`` and positional options if possible. But usage
    of ``List`` action may be useful if you need shell expansion of anything
    other than last positional argument.

    Let's learn rules by example. For the next options::

        ap.refer(&mut lst1).add_option(&["-X", "--xx"], List, "List1");
        ap.refer(&mut lst2).add_argument("yy", List, "List2");

    The following command line::

        ./run 1 2 3 -X 4 5 6

    Will return ``[1, 2, 3]`` in the ``lst1`` and the ``[4,5,6]`` in the
    ``lst2``.

    Note that using when using ``=`` or equivalent short option mode, the
    'consume all' mode is not enabled. I.e. in the following command-line::

        ./run 1 2 -X3 4 --xx=5 6

    The ``lst1`` has ``[3, 5]`` and ``lst2`` has ``[1, 2, 4, 6]``.
    The argument consuming also stops on ``--`` or the next option::

        ./run: -X 1 2 3 -- 4 5 6
        ./run: -X 1 2 --xx=3 4 5 6

    Both of the above parse ``[4, 5, 6]`` as ``lst1`` and
    the ``[1, 2, 3]`` as the ``lst2``.

``Print(value)``
    Print the text and exit (with status ``0``). Useful for ``--version``
    option::

        ap.add_option(&["-V", "--version"],
            Print(env!("CARGO_PKG_VERSION").to_string()), "Show version");