0

I have a use case where users provide a docopt string, and based on it, I generate some code. So I do not know my docopt string up front.

For certain "argument types" (not datatypes), I wish to generate various code.

In the following, I will distinguish between "types" and "datatypes". For the docopt argument --arg=DEGREES and the argv input --arg=10, the "type" of --arg is DEGREES, while the datatype is integer. The value is 10.

A user may give me the following docopt string:

Naval Fate.

Usage:
  naval_fate --dir=FILE [--speed=ABC]

Options:
  --dir=FILE   Moored (anchored) mine.
  --speed=ABC  Speed in knots [default: 10].

Besides parsing this docopt string as usual, I'm trying to also figure out what "type" of argument dir and speed asks for. I want to know that dir is of type FILE and speed is of type ABC.

Example:

Given the above docopt string, and an argv string naval_fate --dir=/tmp --speed 1234, I hope to access not just the value and datatype (<key> => <value,datatype>), but also the "config type" (<key> => <value,datatype,argtype>, i.e. something along the lines of:

dir => val: /tmp, datatype: String, type: FILE
speed => val: 1234, datatype: Integer, type: ABC

Any (managed) implementation of docopt is acceptable, including Python's, though preferably I'm looking for a solution in a compiled language, be it C, Go, Rust etc.

jkgeyti
  • 2,344
  • 18
  • 31
  • Can you add more examples of what you want? It seems I may have misinterpreted your question. – BurntSushi5 Jan 29 '15 at 13:48
  • Sorry for the ambiguity. I've edited my question, and hope it's clearer now. – jkgeyti Jan 29 '15 at 15:09
  • 1
    Neat request. Rust's Docopt does indeed drop this information on the floor. Unfortunately, I don't know if any other Docopt parser makes it available. I opened a new feature request: https://github.com/docopt/docopt.rs/issues/88 – BurntSushi5 Jan 29 '15 at 16:04
  • 1
    Cheers. I'm not convinced adding "non-standard" features to any docopt parser is the right way to go, as the goal must be to have all docopt parsers to behave the same? Maybe some sort of functionality that allows the user to traverse/inspect the parsed docopt document would be the right way to go about it? Anyway, that's probably a discussion best left for the feature request. – jkgeyti Jan 29 '15 at 16:11
  • I've already added some "non-standard" features to docopt.rs. (It's a superset.) And there's some special functionality for type based decoding. I'm not convinced either that adding special introspection features is worthwhile, but I figured I'd file the issue anyway. – BurntSushi5 Jan 29 '15 at 16:46
  • 1
    Ah, didn't realise you were the author of the rust docopt library. Thanks for your good work - it's a neat library :) – jkgeyti Jan 30 '15 at 11:15
  • See https://github.com/docopt/docopt.rs/issues/88 – con-f-use Feb 25 '15 at 12:46

1 Answers1

1

This is pretty easy with Rust's Docopt:

#![allow(unstable)]

extern crate docopt;

use docopt::Docopt;

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

Usage:
    naval_fate ship --dir=FILE [--speed <kn>]
    naval_fate (-h | --help)

Options:
    -h --help     Show this screen.
    --speed <kn>  Speed in knots [default: 10].
    --dir=FILE    Moored (anchored) mine.
";

fn main() {
    let args = Docopt::new(USAGE)
                      .and_then(|d| d.parse())
                      .unwrap_or_else(|e| e.exit());
    println!("Type of 'ship': {:?}", args.find("ship"));
    println!("Type of '--dir': {:?}", args.find("--dir"));
    println!("Type of '--speed': {:?}", args.find("--speed"));
}

Which outputs:

$ ./target/scratch ship --dir /tmp --speed 1234                                        
Type of 'ship': Some(Switch(true))                                                                       
Type of '--dir': Some(Plain(Some("/tmp")))                                                               
Type of '--speed': Some(Plain(Some("1234"))) 

The key is that the return type of find is Value, which is an algebraic data type: http://burntsushi.net/rustdoc/docopt/enum.Value.html --- So by construction, you get the "type" of the argument for free.

Note that this will work for any "argument" in the Docopt usage string, even if it isn't passed into the argument list.

BurntSushi5
  • 13,917
  • 7
  • 52
  • 45
  • Maybe I misinterpreted the question? The OP just wants the string of the argument? – BurntSushi5 Jan 29 '15 at 13:47
  • Yes, I think we mean the same thing. I am indeed looking for determine that the options are DIR and FILE. For future readers: Note that I've simplified the original example, hence why BurntSushi5's example does not correspond 100% to the question. – jkgeyti Jan 29 '15 at 15:11