Разбор типов аргументов docopt (любой язык)

У меня есть вариант использования, когда пользователи предоставляют строку документа, и на ее основе я генерирую некоторый код. Так что я не знаю свою строку docopt заранее.

Для определенных «типов аргументов» (не типов данных) я хочу сгенерировать различный код.

Далее я буду различать «типы» и «типы данных». Для аргумента docopt --arg=DEGREES и ввода argv --arg=10 «тип» --arg равен DEGREES, а тип данных — integer. Значение равно 10.

Пользователь может дать мне следующую строку документа:

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 => значение: /tmp, тип данных: String, тип: FILE
speed => значение: 1234, тип данных: Integer, тип: ABC

Приемлема любая (управляемая) реализация docopt, в том числе Python, хотя предпочтительно я ищу решение на скомпилированном языке, будь то C, Go, Rust и т. д.


person jkgeyti    schedule 29.01.2015    source источник
comment
Можете ли вы добавить больше примеров того, что вы хотите? Кажется, я неправильно истолковал ваш вопрос.   -  person BurntSushi5    schedule 29.01.2015
comment
Извините за двусмысленность. Я отредактировал свой вопрос и надеюсь, что теперь он понятнее.   -  person jkgeyti    schedule 29.01.2015
comment
Аккуратный запрос. Rust Docopt действительно сбрасывает эту информацию на пол. К сожалению, я не знаю, делает ли он доступным какой-либо другой парсер Docopt. Я открыл новый запрос функции: github.com/docopt/docopt.rs/issues/88.   -  person BurntSushi5    schedule 29.01.2015
comment
Ваше здоровье. Я не уверен, что добавление нестандартных функций в любой синтаксический анализатор docopt является правильным путем, поскольку цель должна заключаться в том, чтобы все парсеры docopt вели себя одинаково? Может быть, какая-то функциональность, которая позволяет пользователю просматривать/просматривать проанализированный документ docopt, была бы правильным способом сделать это? В любом случае, это, вероятно, обсуждение, которое лучше всего оставить для запроса функции.   -  person jkgeyti    schedule 29.01.2015
comment
Я уже добавил некоторые нестандартные функции в docopt.rs. (Это надмножество.) И есть некоторые специальные функции для декодирования на основе типов. Я также не уверен, что стоит добавлять специальные функции самоанализа, но я решил, что все равно зарегистрирую проблему.   -  person BurntSushi5    schedule 29.01.2015
comment
Ах, не знал, что вы автор библиотеки rust docopt. Спасибо за вашу хорошую работу - это аккуратная библиотека :)   -  person jkgeyti    schedule 30.01.2015
comment
См. github.com/docopt/docopt.rs/issues/88.   -  person con-f-use    schedule 25.02.2015


Ответы (1)


Это довольно просто с помощью Docopt в Rust:

#![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, даже если он не передан в список аргументов.

person BurntSushi5    schedule 29.01.2015
comment
Может я неправильно понял вопрос? ОП просто хочет строку аргумента? - person BurntSushi5; 29.01.2015
comment
Да, я думаю, мы имеем в виду одно и то же. Я действительно ищу, чтобы определить, что варианты DIR и FILE. Для будущих читателей: обратите внимание, что я упростил исходный пример, поэтому пример BurntSushi5 не соответствует вопросу на 100%. - person jkgeyti; 29.01.2015