前言

在上一篇文章中,我们搭建好了 Tauri 环境,早就想迫不及待的进行开发了。

Taur 使用 Web+Rust 技术,所以今天来了解一下如何从 Web 中调用 Rust

Web 调用 Rust

要想在 Web 中调用 Rust 代码,需要在指定的函数上加入 #[tauri::command] 属性,如下所示

1
2
3
4
#[tauri::command]
fn greet(name: &str) -> String {
   format!("Hello, {}!", name)
}

这个函数接收一个字符串切片,然后我们在其前面添加了 Hello, 并返回给了调用者。

仅仅这样做是不够的,我们还要告诉 Tauri 这个函数可以在 Web 中调用。

src-tauri/main.rs 中的 main 函数就有这么一句话来做这个事情

1
2
3
4
5
6
fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

invoke_handler 中,我们使用 tauri::genrate_handler! 这个宏,把 greet 传进去了,这样就能从 Web 中调用了。

tauri::generate_handler! 的参数是个数组,所以这里可以放多个函数。

做好了上面的工作,就可以在 Web 中可以通过 invoke 来调用 Rust 函数

1
2
3
import { invoke } from '@tauri-apps/api/tauri'

invoke('greet', {name: 'Tauri'})

传递参数

任意数据类型

Web 在给 Rust 传递参数可以是任何类型,但是要实现了 serde::Serialize

在传递结构体数据时,要按照 JSON 的格式进行传递。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#[derive(Debug, serde::Serialize)]
pub struct Args {
    pub arg1: String,
    pub arg2: String
}

#[tauri::command]
fn greet(args: Args) {
  println!("args: {:?}", args);
}

调用

1
invoke('greet', {arg1: 'arg1', arg2: 'arg2'})

Window

有时候我们想要操作 Window ,在函数中只需要定义这个变量就行

1
2
3
4
#[tauri::command]
fn greet(window: tauri::Window) {
  println!("Window: {}", window.label());
}

这样我们就可以在 Web 中直接调用 greet ,不用传参数, window 这个参数 tauri 会自动帮你赋值,如下所示

1
invoke('greet')

AppHandle

AppHandle 中提供了许多方法,让我们可以方便的访问一些资源,比如查找应用内的资源,应用配置存放的路径等等。

使用 AppHandleWindow 一样,只需要在函数中定义就行

1
2
3
4
5
#[tauri::command]
fn greet(app_handle: tauri::AppHandle) {
    let app_dir = app_handle.path_resolver().app_dir();
    println!("app dir: {:?}", app_dir);
}

错误处理

Rust 是有专门处理错误的类型 Result ,在 Tauri 中也能使用

1
2
3
4
5
6
7
#[tauri::command]
fn greet() -> Result<String, String> {
  // If something fails
  Err("This failed!".into())
  // If it worked
  Ok("This worked!".into())
}

我们把 greet 改成了一个可以返回错误的函数,正常情况返回 This worked! 发生错误返回 This failed!

Web 中就可以通过 Promise 来分别处理正常和错误的情况,如下所示

1
2
3
invoke('greet')
  .then((message) => console.log(message))
  .catch((error) => console.error(error))

参考

从前端调用 Rust | Tauri Apps