【发布时间】:2017-05-24 14:04:15
【问题描述】:
我正在编写一个用于解析 OVPN 配置文件的小库。 OVPN 配置文件有这种格式
command arg1 arg2
othercommand arg1 arg2
有一组固定的命令,其中一些具有可选参数。我想将解析的命令表示为枚举。所以上面的内容最终可能会这样表示:
enum ConfigDirective{
Command{arg1: String},
OtherCommand{arg1: String, optinal_arg1: Option<String>},
}
fn parse_line(command: String, args: Vec<String>) -> ConfigDirective {
match command {
"command" => ConfigDirective::Command{arg1: args[0]},
"other_command" => ConfigDirective:OtherCommand{arg1: args[0], optional_arg1: args.get(1),
}
}
我喜欢这种结构,但有很多可能的命令(大约 280 个区域)。所以我想写一个宏来生成大部分样板文件。理想情况下,我会写如下内容:
define_config_directive!{
{command => "command1", rust_name => CommandOne, args => [arg1], optional_args => []},
{command => "other_command", rust_name => OtherCommand, args => [arg1], optional_args => [optional_arg1]},
}
到目前为止,我能做到的最接近的是:
macro_rules! define_config_directives {
($({
rust_name => $rust_name:ident,
required => [$($required:ident),*],
optional => [$($optional:ident),*]
}),*) => {
#[derive(PartialEq, Eq, Debug)]
pub enum ConfigDirective {
$($rust_name{
$($required: String),*,
$($optional: Option<String>),*,
}),*
}
};
}
所以我有几个问题:
- 我不知道如何在这个宏中实现
parse_line函数,我需要遍历每个必需的参数,以便编写一些代码将相应的参数拉出行外,对于可选参数也是如此李> - 我不知道如何处理根本没有参数的情况,理想情况下这将是一个没有字段的简单枚举变体。
有谁知道是否有办法解决稳定生锈的问题?还是我应该只使用 python 脚本生成代码?
【问题讨论】:
-
注意:宏和外部脚本之间的中间步骤是
build.rs文件。使用cargo build时,cargo 将首先编译并执行build.rs(如果存在),然后再编译其余的 crate,因此您可以轻松使用build.rs生成 Rust 代码,而无需涉及任何 3rd 方工具/makefile。跨度>