首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从` `syn:: parse ::ParseStream`中解析出` `syn::Signature`?

如何从` `syn:: parse ::ParseStream`中解析出` `syn::Signature`?
EN

Stack Overflow用户
提问于 2020-07-27 23:43:45
回答 2查看 528关注 0票数 2

我正在试验Rust过程宏。

我希望能够创建一个宏,用于生成JNI调用样板。就像这样

代码语言:javascript
复制
jni_method!{com.purplefrog.rust_callable.Widget, fn echo_str(&str)->String}

到目前为止,我有以下代码(playground):

代码语言:javascript
复制
#[macro_use]
extern crate syn; // 1.0.33

use syn::parse::{Parse, ParseStream};
use syn::Signature;

struct Arguments {
    name: proc_macro2::Ident,
    signature: Signature,
}

impl Parse for Arguments {
    fn parse(tokens: ParseStream) -> Result<Arguments, syn::Error> {
        let name: proc_macro2::Ident = tokens.parse()?;
        let comma: Token![,] = tokens.parse()?;
        let signature: Signature = //tokens.parse()?;
            syn::item::parsing::parse_signature(tokens)?;

        Ok(Arguments {
            name: name,
            signature,
        })
    }
}

不幸的是,parse_signature调用出错:

代码语言:javascript
复制
error[E0603]: module `item` is private
   --> src/lib.rs:17:18
    |
17  |             syn::item::parsing::parse_signature(tokens)?;
    |                  ^^^^ private module
    |
note: the module `item` is defined here
   --> /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/syn-1.0.33/src/lib.rs:363:1
    |
363 | mod item;
    | ^^^^^^^^^

ParseStream解析Signature的正确方法是什么

EN

回答 2

Stack Overflow用户

发布于 2020-07-29 06:13:37

为什么需要Signature?根据您实际尝试解析的内容,您应该使用以下方法之一:

  • Fn* 特征签名(例如FnMut(usize) -> bool)

解析成syn::TraitBound (为了捕捉不存在于路径中的生存期界限),然后您可以从特征界限路径的最后一段的带括号的参数中获得输入/输出。

  • Bare函数,也称为函数指针(例如fn(usize) -> bool)

解析成syn::TypeBareFn,然后您可以直接获得输入/输出。

  • Function定义,包括主体(例如fn foo(x: usize) -> bool { x > 5 })

解析成包含签名的syn::ItemFn

  • Foreign函数定义(例如fn foo(x: usize) -> bool)

解析成包含签名的Struct syn::ForeignItemFn。请注意,这是针对extern块中的声明的,因此很可能这并不是您实际要查找的内容。

票数 1
EN

Stack Overflow用户

发布于 2021-09-01 13:19:03

我最终找到了一个如何解决此问题的示例( https://github.com/dtolnay/syn/blob/master/examples/lazy-static/lazy-static/src/lib.rs )。你应该为它创建你自己的structimpl Parse。我能够从支持Parse的元素构建自己的语法。

代码语言:javascript
复制
struct MySignature {
    pub parameter_types: Vec<Type>,
}

impl Parse for MySignature {
    fn parse(tokens: ParseStream) -> Result<Self, syn::Error> {
        let mut parameter_types: Vec<Type> = Vec::new();

        let arg_types: ParseBuffer;
        parenthesized!(arg_types in tokens);

        while !arg_types.is_empty() {
            let arg_type: Type = arg_types.parse()?;
            parameter_types.push(arg_type);

            if !arg_types.is_empty() {
                let _comma: Token![,] = arg_types.parse()?;
            }
        }

        Ok(MySignature { parameter_types })
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63118772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档