Skip to content

Commit 39f8f26

Browse files
authored
refactor(macros): explicitly pass idents (#1812)
1 parent 64dd434 commit 39f8f26

3 files changed

Lines changed: 49 additions & 35 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-macros": patch
3+
---
4+
5+
internal: Refactor all macro code that expects specific bindings to be passed Idents

‎core/tauri-macros/src/command/handler.rs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use quote::format_ident;
56
use syn::{
67
parse::{Parse, ParseBuffer},
78
Ident, Path, Token,
@@ -51,12 +52,14 @@ impl From<Handler> for proc_macro::TokenStream {
5152
wrappers,
5253
}: Handler,
5354
) -> Self {
54-
quote::quote!(move |__tauri_invoke__| {
55-
let __tauri_cmd__ = __tauri_invoke__.message.command();
56-
match __tauri_cmd__ {
57-
#(stringify!(#commands) => #wrappers!(#paths, __tauri_invoke__),)*
55+
let cmd = format_ident!("__tauri_cmd__");
56+
let invoke = format_ident!("__tauri_invoke__");
57+
quote::quote!(move |#invoke| {
58+
let #cmd = #invoke.message.command();
59+
match #cmd {
60+
#(stringify!(#commands) => #wrappers!(#paths, #invoke),)*
5861
_ => {
59-
__tauri_invoke__.resolver.reject(format!("command {} not found", __tauri_cmd__))
62+
#invoke.resolver.reject(format!("command {} not found", #cmd))
6063
},
6164
}
6265
})

‎core/tauri-macros/src/command/wrapper.rs‎

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use proc_macro::TokenStream;
66
use proc_macro2::TokenStream as TokenStream2;
7-
use quote::quote;
7+
use quote::{format_ident, quote};
88
use syn::{
99
parse::{Parse, ParseBuffer},
1010
parse_macro_input,
@@ -36,6 +36,12 @@ impl Parse for ExecutionContext {
3636
}
3737
}
3838

39+
/// The bindings we attach to `tauri::Invoke`.
40+
struct Invoke {
41+
message: Ident,
42+
resolver: Ident,
43+
}
44+
3945
/// Create a new [`Wrapper`] from the function and the generated code parsed from the function.
4046
pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
4147
let function = parse_macro_input!(item as ItemFn);
@@ -48,18 +54,25 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
4854
_ => Default::default(),
4955
};
5056

57+
let invoke = Invoke {
58+
message: format_ident!("__tauri_message__"),
59+
resolver: format_ident!("__tauri_resolver__"),
60+
};
61+
5162
// body to the command wrapper or a `compile_error!` of an error occurred while parsing it.
5263
let body = syn::parse::<ExecutionContext>(attributes)
5364
.map(|context| match function.sig.asyncness {
5465
Some(_) => ExecutionContext::Async,
5566
None => context,
5667
})
5768
.and_then(|context| match context {
58-
ExecutionContext::Async => body_async(&function),
59-
ExecutionContext::Blocking => body_blocking(&function),
69+
ExecutionContext::Async => body_async(&function, &invoke),
70+
ExecutionContext::Blocking => body_blocking(&function, &invoke),
6071
})
6172
.unwrap_or_else(syn::Error::into_compile_error);
6273

74+
let Invoke { message, resolver } = invoke;
75+
6376
// Rely on rust 2018 edition to allow importing a macro from a path.
6477
quote!(
6578
#function
@@ -68,16 +81,9 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
6881
macro_rules! #wrapper {
6982
// double braces because the item is expected to be a block expression
7083
($path:path, $invoke:ident) => {{
71-
// import all the autoref specialization items
72-
#[allow(unused_imports)]
73-
use ::tauri::command::private::*;
74-
7584
// prevent warnings when the body is a `compile_error!` or if the command has no arguments
7685
#[allow(unused_variables)]
77-
let ::tauri::Invoke {
78-
message: __tauri_message__,
79-
resolver: __tauri_resolver__
80-
} = $invoke;
86+
let ::tauri::Invoke { message: #message, resolver: #resolver } = $invoke;
8187

8288
#body
8389
}};
@@ -94,14 +100,15 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
94100
///
95101
/// See the [`tauri::command`] module for all the items and traits that make this possible.
96102
///
97-
/// * Requires binding `__tauri_message__` and `__tauri_resolver__`.
98-
/// * Requires all the traits from `tauri::command::private` to be in scope.
99-
///
100103
/// [`tauri::command`]: https://docs.rs/tauri/*/tauri/runtime/index.html
101-
fn body_async(function: &ItemFn) -> syn::Result<TokenStream2> {
102-
parse_args(function).map(|args| {
104+
fn body_async(function: &ItemFn, invoke: &Invoke) -> syn::Result<TokenStream2> {
105+
let Invoke { message, resolver } = invoke;
106+
parse_args(function, message).map(|args| {
103107
quote! {
104-
__tauri_resolver__.respond_async_serialized(async move {
108+
#[allow(unused_imports)]
109+
use ::tauri::command::private::*;
110+
111+
#resolver.respond_async_serialized(async move {
105112
let result = $path(#(#args?),*);
106113
let kind = (&result).async_kind();
107114
kind.future(result).await
@@ -114,40 +121,39 @@ fn body_async(function: &ItemFn) -> syn::Result<TokenStream2> {
114121
///
115122
/// See the [`tauri::command`] module for all the items and traits that make this possible.
116123
///
117-
/// * Requires binding `__tauri_message__` and `__tauri_resolver__`.
118-
/// * Requires all the traits from `tauri::command::private` to be in scope.
119-
///
120124
/// [`tauri::command`]: https://docs.rs/tauri/*/tauri/runtime/index.html
121-
fn body_blocking(function: &ItemFn) -> syn::Result<TokenStream2> {
122-
let args = parse_args(function)?;
125+
fn body_blocking(function: &ItemFn, invoke: &Invoke) -> syn::Result<TokenStream2> {
126+
let Invoke { message, resolver } = invoke;
127+
let args = parse_args(function, message)?;
123128

124129
// the body of a `match` to early return any argument that wasn't successful in parsing.
125130
let match_body = quote!({
126131
Ok(arg) => arg,
127-
Err(err) => return __tauri_resolver__.invoke_error(err),
132+
Err(err) => return #resolver.invoke_error(err),
128133
});
129134

130135
Ok(quote! {
136+
#[allow(unused_imports)]
137+
use ::tauri::command::private::*;
138+
131139
let result = $path(#(match #args #match_body),*);
132140
let kind = (&result).blocking_kind();
133-
kind.block(result, __tauri_resolver__);
141+
kind.block(result, #resolver);
134142
})
135143
}
136144

137145
/// Parse all arguments for the command wrapper to use from the signature of the command function.
138-
fn parse_args(function: &ItemFn) -> syn::Result<Vec<TokenStream2>> {
146+
fn parse_args(function: &ItemFn, message: &Ident) -> syn::Result<Vec<TokenStream2>> {
139147
function
140148
.sig
141149
.inputs
142150
.iter()
143-
.map(|arg| parse_arg(&function.sig.ident, arg))
151+
.map(|arg| parse_arg(&function.sig.ident, arg, message))
144152
.collect()
145153
}
146154

147155
/// Transform a [`FnArg`] into a command argument.
148-
///
149-
/// * Requires binding `__tauri_message__`.
150-
fn parse_arg(command: &Ident, arg: &FnArg) -> syn::Result<TokenStream2> {
156+
fn parse_arg(command: &Ident, arg: &FnArg, message: &Ident) -> syn::Result<TokenStream2> {
151157
// we have no use for self arguments
152158
let mut arg = match arg {
153159
FnArg::Typed(arg) => arg.pat.as_ref().clone(),
@@ -190,7 +196,7 @@ fn parse_arg(command: &Ident, arg: &FnArg) -> syn::Result<TokenStream2> {
190196
::tauri::command::CommandItem {
191197
name: stringify!(#command),
192198
key: #key,
193-
message: &__tauri_message__,
199+
message: &#message,
194200
}
195201
)))
196202
}

0 commit comments

Comments
 (0)