英文:
Parsing docopt argument types (any language)
问题
我有一个使用情况,用户提供一个docopt字符串,我根据它生成一些代码。所以我事先不知道我的docopt字符串。
对于某些“参数类型”(而不是数据类型),我希望生成各种代码。
在接下来的内容中,我将区分“类型”和“数据类型”。对于docopt参数--arg=DEGREES
和argv输入--arg=10
,--arg
的“类型”是DEGREES
,而数据类型是integer
。值是10
。
用户可能给我以下docopt字符串:
Naval Fate.
Usage:
naval_fate --dir=FILE [--speed=ABC]
Options:
--dir=FILE Moored (anchored) mine.
--speed=ABC Speed in knots [default: 10]。
除了像往常一样解析这个docopt字符串,我还试图弄清楚dir
和speed
参数所要求的“类型”。我想知道dir
的类型是FILE
,speed
的类型是ABC
。
示例:
给定上述docopt字符串和argv字符串naval_fate --dir=/tmp --speed 1234
,我希望不仅可以访问值和数据类型(<key> => <value,datatype>
),还可以访问“配置类型”(<key> => <value,datatype,argtype>
),即类似以下内容:
dir
=> val: /tmp
,数据类型:String
,类型:FILE
speed
=> val: 1234
,数据类型:Integer
,类型:ABC
任何(可管理的)docopt实现都可以接受,包括Python的实现,但最好是在编译语言中找到解决方案,比如C、Go、Rust等。
英文:
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.
答案1
得分: 1
这在Rust的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"));
}
输出结果为:
$ ./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")))
关键是find
的返回类型是Value
,它是一个代数数据类型:http://burntsushi.net/rustdoc/docopt/enum.Value.html --- 因此,通过构造,你可以免费获得参数的“类型”。
请注意,这适用于Docopt使用字符串中的任何“参数”,即使它没有传递到参数列表中。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论