【Tauri2】005——tauri::command属性与invoke函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146581991?spm=1001.2014.3001.5502前面说过,通信函数greet被属性command修饰,在代码模板中创造了宏__cmd__greet
这里就介绍一下怎么注册的
.invoke_handler(tauri::generate_handler![greet])
#[proc_macro]
pub fn generate_handler(item: TokenStream) -> TokenStream {
parse_macro_input!(item as command::Handler).into()
}
注册其实很简单。
点击Hnadler,发现这是一个结构体,为这个结构体实现一个trait Parse
pub struct Handler {
command_defs: Vec,
commands: Vec,
wrappers: Vec,
}
impl Parse for Handler
pub trait Parse: Sized {
fn parse(input: ParseStream) -> Result;
}
需要实现Parse中的parse方法,在这个parse函数中实现了注册
给出关键代码
for command_def in &command_defs {
let mut wrapper = command_def.path.clone();
println!("{:?}", wrapper);
let last = super::path_to_command(&mut wrapper);
println!("{:?}", last);
// the name of the actual command function
let command = last.ident.clone();
println!("{:?}", command);
// set the path to the command function wrapper
last.ident = super::format_command_wrapper(&command);
println!("{:?}", last.ident);
commands.push(command);
wrappers.push(wrapper);
}
command_defs 是Vec
因为CommandDef 的定义如下
struct CommandDef {
path: Path,
attrs: Vec,
}
CommandDef 这个结构体,有两个字段。path和attrs
先从commandDef中取出path。结果如下
Path {
leading_colon: None,
segments: [PathSegment{ ident: Ident { ident: "greet", span: #0 bytes(361..366) },
arguments:PathArguments::None }
]
}
Path里面有两个字段leading_colon和segments,对于segments里面又有PathSegment
PathSegment {
ident: Ident { ident: "greet", span: #0 bytes(361..366) },
arguments: PathArguments::None
}
很明显,中间过程就是实现这个获取PathSegment过程
Ident { ident: "greet", span: #0 bytes(361..366) }
就是从PathSegment取出ident
在Ident 中有个字段ident
Ident { ident: "__cmd__greet", span: #0 bytes(361..366) }
greet变成了__cmd__greet
完成了注册。
在第三个和第四个打印语句之间,其实就一个很简单的函数
fn format_command_wrapper(function: &Ident) -> Ident {
quote::format_ident!("__cmd__{}", function)
}
调用了这个函数,加上__cmd__前缀。
解析完成。很简单。