File tree 3 files changed +37
-7
lines changed
3 files changed +37
-7
lines changed Original file line number Diff line number Diff line change @@ -171,6 +171,23 @@ impl Megaphone {
171
171
}
172
172
}
173
173
174
+ // The async_runtime attribute used to error when *any* function in the impl block was not async,
175
+ // now it should work as long as at least one function *is* async.
176
+ #[ uniffi:: export( async_runtime = "tokio" ) ]
177
+ impl Megaphone {
178
+ /// A sync method that yells something immediately.
179
+ pub fn say_now ( & self , who : String ) -> String {
180
+ format ! ( "Hello, {who}!" ) . to_uppercase ( )
181
+ }
182
+
183
+ /// An async method that yells something after a certain time.
184
+ ///
185
+ /// Uses tokio's timer functionality.
186
+ pub async fn say_after_with_tokio ( self : Arc < Self > , ms : u16 , who : String ) -> String {
187
+ say_after_with_tokio ( ms, who) . await . to_uppercase ( )
188
+ }
189
+ }
190
+
174
191
// Say something after a certain amount of time, by using `tokio::time::sleep`
175
192
// instead of our own `TimerFuture`.
176
193
#[ uniffi:: export( async_runtime = "tokio" ) ]
Original file line number Diff line number Diff line change @@ -42,6 +42,18 @@ pub(crate) fn expand_export(
42
42
match metadata {
43
43
ExportItem :: Function { sig } => gen_fn_scaffolding ( sig, & args) ,
44
44
ExportItem :: Impl { items, self_ident } => {
45
+ if let Some ( rt) = & args. async_runtime {
46
+ if items
47
+ . iter ( )
48
+ . all ( |item| !matches ! ( item, ImplItem :: Method ( sig) if sig. is_async) )
49
+ {
50
+ return Err ( syn:: Error :: new_spanned (
51
+ rt,
52
+ "no async methods in this impl block" ,
53
+ ) ) ;
54
+ }
55
+ }
56
+
45
57
let item_tokens: TokenStream = items
46
58
. into_iter ( )
47
59
. map ( |item| match item {
Original file line number Diff line number Diff line change @@ -19,6 +19,14 @@ pub(super) fn gen_fn_scaffolding(
19
19
"Unexpected self param (Note: uniffi::export must be used on the impl block, not its containing fn's)"
20
20
) ) ;
21
21
}
22
+ if !sig. is_async {
23
+ if let Some ( async_runtime) = & arguments. async_runtime {
24
+ return Err ( syn:: Error :: new_spanned (
25
+ async_runtime,
26
+ "this attribute is only allowed on async functions" ,
27
+ ) ) ;
28
+ }
29
+ }
22
30
let metadata_items = sig. metadata_items ( ) ?;
23
31
let scaffolding_func = gen_ffi_function ( & sig, arguments) ?;
24
32
Ok ( quote ! {
@@ -157,13 +165,6 @@ fn gen_ffi_function(
157
165
let return_ty = & sig. return_ty ;
158
166
159
167
Ok ( if !sig. is_async {
160
- if let Some ( async_runtime) = & arguments. async_runtime {
161
- return Err ( syn:: Error :: new_spanned (
162
- async_runtime,
163
- "this attribute is only allowed on async functions" ,
164
- ) ) ;
165
- }
166
-
167
168
quote ! {
168
169
#[ doc( hidden) ]
169
170
#[ no_mangle]
You can’t perform that action at this time.
0 commit comments