docopt/docopt.rs — pull request #31 by alexcrichton (2014-10-17 22:03:57+00:00)
Title: Allow generic decoding of usage into a type

When writing a generic decode function over any types, one is tempted to write
something along the lines of:

extern crate serialize;
extern crate docopt;
use serialize::Decodable;

fn foo<'a, T>(usage: &str) -> T
where T: Decodable, docopt::Error> {
let map = docopt::docopt(usage).unwrap_or_else(|e| e.exit());
map.decode().unwrap_or_else(|e| e.exit())
}

Currently there are two problems with this approach.

1. The `docopt::Decoder` structure is private, so it cannot be referenced in a
function signature.
2. The lifetime parameter on `Decoder` prevents usage of the local variable
`map`. The `decode` function requires `&'a self`, which requires callers of
this function to provide a lifetime variable `'a` which is the lifetime of
the stack frame of `foo` itself. Sadly this cannot currently be done (higher
ranked trait lifetimes maybe?).

To work around these two problems, I've made the `Decoder` structure public and
changed the `decode` method on `ValueMap` to consume the map, removing the
lifetime parameter on `Decoder`.

There may be some more generic wizardry to get around this problem, but this at
least seems to work for now! Does this seem ok to you?