【Tauri2】003——run函数的简单介绍(1)
前言
【Tauri2】002——Cargo.toml和入口文件-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146489094?spm=1001.2014.3001.5501
前面介绍就入口文件,其中lib.rs中的run函数是非常关键,这篇就看run函数
正文
代码如下
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
第一行
#[cfg_attr(mobile, tauri::mobile_entry_point)]
cfg_attr用于在某个condition下设置attribute。
mobile英文意思是移动,因此,这行代码的意思是在移动端时,设置属性tauri::mobile_entry_point
可以简单的查看一下里面的属性,在run.rs文件最上面写下如下代码
use tauri::mobile_entry_point;
笔者在RustRover中,按住ctrl,鼠标左键点击mobile_entry_point,就可以查看源代码
如下
#[proc_macro_attribute]
pub fn mobile_entry_point(attributes: TokenStream, item: TokenStream) -> TokenStream {
mobile::entry_point(attributes, item)
}
最上面这个proc_macro_attribute这个标志,正是属性宏。不看这个标志的话,下面是函数,这个属性宏,把函数变成了可以附加到程序项上的新的外部属性。
过程宏 - Rust 参考手册 中文版https://rustwiki.org/zh-CN/reference/procedural-macros.html
简单的使用一下这个宏
不妨新建一个Cargo项目test1,在test1中新建一个crate——macros,这是一个library crate
macros中新建lib.rs目录,Cargo.toml配置日系
[package]
name = "macros"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
这个proc-macro设为true是非常关键的
test1的配置文件
[package]
name = "test1"
version = "0.1.0"
edition = "2024"
[dependencies]
macros={path = "./macros"}
大致结构如下
在lib.rs中,随便写个属性宏
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn window_print(attr:TokenStream,item:TokenStream)->TokenStream{
println!("11111111");
println!("{:?}",attr);
println!("2222222222");
println!("{:?}",item);
TokenStream::from(attr)
}
在main.rs的代码如下
use macros::window_print;
#[cfg_attr(debug_assertions,window_print)]
pub fn run() {
println!("Hello from macro!");
}
fn main() {
}
运行命令cargo run
可以看到
第一个参数是空的,第二个参数把Rust的函数变成了标记流(TokenStream),
为什么这么做?
如果再进入属性proc_macro_attribute中,可以发现是在tauri-macros中
再打开tauri-macros的配置文件,可以发现几个依赖
发现有两个重要的依赖,syn和quote。syn - Rusthttps://docs.rs/syn/latest/syn/
quote - Rusthttps://docs.rs/quote/latest/quote/笔者能力有限,只知道大概的操作过程
syn主要把TokenStream变成AST(抽象语法树)
quote主要把AST变成TokenStream,
在这变化的中间过程,通过代码模板处理在移动端的代码。
简单使用一下syn和quote
在macros的配置文件中,添加依赖
[dependencies]
syn = {version = "2.0.100",features = ["full","extra-traits"]}
quote = "1.0.40"
full的意思是使用全特性。
extra-trait意思是启动额外的特性,用于调试。
修改macros中的window_print
use proc_macro::TokenStream;
use syn::{parse_macro_input,ItemFn};
use quote::{quote,format_ident};
#[proc_macro_attribute]
pub fn window_print(_:TokenStream,item:TokenStream)->TokenStream{
// 对传入的函数进行解析
let fn_=parse_macro_input!(item as ItemFn);
println!("{:#?}",fn_);
// 获取函数名
let fn_name=&fn_.sig.ident;
println!("fn_name={:?}",fn_name);
// 生成结构体的名字
let fn_struct=format_ident!("{}_wrapper",fn_name);
// 生成新的代码
let result=quote! {
// 保留原函数
#fn_
// 代码模板
// 结构体
pub struct #fn_struct;
//为结构体实现方法
impl #fn_struct{
pub fn print(){
println!("代码模板")
}
}
};
// 返回TokenStream
result.into()
}
调用属性宏
use macros::window_print;
#[window_print]
pub fn run() {
println!("Hello from macro!");
}
fn main() {
run();
run_wrapper::print();
}
虽然会报错,但是可以运行cargo run
结果如下
打印了代码模板。
在mobile_entry_point中实现的过程类似。肯定更复杂,笔者不深究。
总之,第一行代码,就是在处理移动端的情况