【问题标题】:Rust proc_macro_derive (with syn crate) generating enum variant for matchingRust proc_macro_derive (with syn crate) 生成用于匹配的枚举变体
【发布时间】:2020-04-19 20:22:45
【问题描述】:

我是 rust 新手,我是一周前开始的,但这种语言已经非常令人兴奋了。我正在用 rust 重写一个 nodejs 项目以获得更好的性能,目前它的速度有多快真是太疯狂了。

我实际上正在编写一个 proc_derive_macro(使用“syn”板条箱)以在某些特定结构上生成方法。我快完成了,但我不知道如何生成枚举变体。我会试着解释一下自己。

这是我的代码生成(使用引号!)

quote! {
        // The generated impl.
        impl #name /*#ty_generics #where_clause*/ {
            pub fn from_config(config: &IndicatorConfig) -> Result<Self, Error> {
                let mut #name_lower = #name::default()?;
                for (k, v) in config.opts.iter() {
                    println!("{:?} {:?}", k, v);
                    match (k.as_str(), v) {
                        ("label", Values::String(val)) => {
                            #name_lower.label = val.clone();
                        }
                        ("agg_time", Values::String(val)) => {
                            #name_lower.agg_time = Some(val.clone());
                        }
                        #(
                            (#fields_name_str, Values::Unteger(val)) => {
                                #name_lower.#fields_name = val.clone();
                            }
                        )*
                        (&_, _) => {}
                    }
                }
                #name_lower.init()?;
                Ok(#name_lower)
            }
        }
    };

正如我们所见,我在这里生成了大部分代码

(#fields_name_str, Values::Unteger(val)) => {
   #name_lower.#fields_name = val.clone();
}

但是我没有找到一种方法来生成“匹配的枚举变体”(我不知道我们怎么称呼它,希望你能理解):

Values::String(val)
OR
Values::Unteger(val)
...

我正在编写一个函数,它将根据结构内的参数类型创建变体匹配:

fn create_variant_match(ty: &str) -> PatTupleStruct {
    let variant = match ty {
        "u32" => Ident::new("Unteger", Span::call_site()),
        ...
        _ => unimplemented!(),
    };
}

实际上我正在创建一个标识,但我想创建“枚举变体匹配”-> Values::Unteger(val)。

我看了同步箱的文档,花了几个小时试图找到一种方法,但对于我的实际水平来说有点复杂,所以我希望有人能解释一下如何做到这一点。

【问题讨论】:

    标签: enums rust


    【解决方案1】:

    我找到了一种简单的方法。只需要使用 syn 解析器解析一个字符串(我可以之前格式化)。 之前没想过是想手工构造Expr(有点傻^^)

    syn::parse_str::<Expr>("Values::Unteger(val)")
    

    这将生成所需的 Expr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 2023-02-14
      相关资源
      最近更新 更多