tauri_invoke/
lib.rs

1//! A simple way to call invoke in [tauri](https://crates.io/crates/tauri) from rust.
2//!
3//! ```rust
4//! // define an invoke
5//! tauri_invoke::invoke!(async fn example_invoke(foo: f32, bar: bool) -> String);
6//!
7//! // call the invoke
8//! let future = example_invoke(1.0, false);
9//! ```
10
11use wasm_bindgen::prelude::*;
12
13#[doc(hidden)]
14pub use js_sys;
15#[doc(hidden)]
16pub use serde;
17#[doc(hidden)]
18pub use serde_wasm_bindgen;
19#[doc(hidden)]
20pub use wasm_bindgen;
21#[doc(hidden)]
22pub use wasm_bindgen_futures;
23
24#[wasm_bindgen]
25extern "C" {
26    #[doc(hidden)]
27    #[wasm_bindgen(js_namespace = window)]
28    pub fn __TAURI_INVOKE__(name: &str, arguments: JsValue) -> JsValue;
29}
30
31#[doc(hidden)]
32pub type InvokeResult<T = ()> = Result<T, String>;
33
34/// # Examples
35/// ```rust
36/// // define an invoke
37/// tauri_invoke::invoke!(async fn example_invoke(foo: f32, bar: bool) -> String);
38///
39/// // call the invoke
40/// let future = example_invoke(1.0, false);
41/// ```
42#[macro_export]
43macro_rules! invoke {
44    { $( $vis:vis async fn $name:ident ( $($arg:ident : $arg_ty:ty),* $(,)? ) $(-> $ty:ty)? ; )* } => {
45        $crate::invoke!($( $vis async fn $name($($arg: $arg_ty),*) $(-> $ty)? ),*);
46    };
47    { $( $vis:vis async fn $name:ident ( $($arg:ident : $arg_ty:ty),* $(,)? ) $(-> $ty:ty)? ),* $(,)? } => {$(
48        $vis async fn $name($($arg: $arg_ty),*) -> $crate::InvokeResult$(<$ty>)? {
49            let args = $crate::js_sys::Object::new();
50            let serializer = $crate::serde_wasm_bindgen::Serializer::json_compatible();
51
52            $(
53                $crate::js_sys::Reflect::set(
54                    &args,
55                    &$crate::wasm_bindgen::JsValue::from_str(::std::stringify!($arg)),
56                    &$crate::serde::Serialize::serialize(&$arg, &serializer).unwrap(),
57                ).expect("failed to set argument");
58            )*
59
60            let output = $crate::__TAURI_INVOKE__(
61                ::std::stringify!($name),
62                ::std::convert::From::from(args),
63            );
64
65            let promise = $crate::js_sys::Promise::from(output);
66            let result = $crate::wasm_bindgen_futures::JsFuture::from(promise).await;
67
68            Ok(match result {
69                #[allow(unused_variables)]
70                ::std::result::Result::Ok(value) => {$(
71                    $crate::serde_wasm_bindgen::from_value::<$ty>(value)
72                        .expect("Failed to deserialize output of invoke, maybe the type is wrong?")
73                )?},
74                ::std::result::Result::Err(err) => {
75                    return ::std::result::Result::Err(err.as_string().unwrap());
76                }
77            })
78        }
79    )*};
80}