Skip to content

Commit

Permalink
Relax async_runtime check on impl blocks
Browse files Browse the repository at this point in the history
It used to error out if there were any non-async functions, now it only
errors if there are no async functions in the impl block.
  • Loading branch information
jplatte committed Jul 11, 2023
1 parent b18d6b7 commit b7d7bbd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
17 changes: 17 additions & 0 deletions fixtures/futures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,23 @@ impl Megaphone {
}
}

// The async_runtime attribute used to error when *any* function in the impl block was not async,
// now it should work as long as at least one function *is* async.
#[uniffi::export(async_runtime = "tokio")]
impl Megaphone {
/// A sync method that yells something immediately.
pub fn say_now(&self, who: String) -> String {
format!("Hello, {who}!").to_uppercase()
}

/// An async method that yells something after a certain time.
///
/// Uses tokio's timer functionality.
pub async fn say_after_with_tokio(self: Arc<Self>, ms: u16, who: String) -> String {
say_after_with_tokio(ms, who).await.to_uppercase()
}
}

// Say something after a certain amount of time, by using `tokio::time::sleep`
// instead of our own `TimerFuture`.
#[uniffi::export(async_runtime = "tokio")]
Expand Down
12 changes: 12 additions & 0 deletions uniffi_macros/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ pub(crate) fn expand_export(
match metadata {
ExportItem::Function { sig } => gen_fn_scaffolding(sig, &args),
ExportItem::Impl { items, self_ident } => {
if let Some(rt) = &args.async_runtime {
if items
.iter()
.all(|item| !matches!(item, ImplItem::Method(sig) if sig.is_async))
{
return Err(syn::Error::new_spanned(
rt,
"no async methods in this impl block",
));
}
}

let item_tokens: TokenStream = items
.into_iter()
.map(|item| match item {
Expand Down
15 changes: 8 additions & 7 deletions uniffi_macros/src/export/scaffolding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ pub(super) fn gen_fn_scaffolding(
"Unexpected self param (Note: uniffi::export must be used on the impl block, not its containing fn's)"
));
}
if !sig.is_async {
if let Some(async_runtime) = &arguments.async_runtime {
return Err(syn::Error::new_spanned(
async_runtime,
"this attribute is only allowed on async functions",
));
}
}
let metadata_items = sig.metadata_items()?;
let scaffolding_func = gen_ffi_function(&sig, arguments)?;
Ok(quote! {
Expand Down Expand Up @@ -157,13 +165,6 @@ fn gen_ffi_function(
let return_ty = &sig.return_ty;

Ok(if !sig.is_async {
if let Some(async_runtime) = &arguments.async_runtime {
return Err(syn::Error::new_spanned(
async_runtime,
"this attribute is only allowed on async functions",
));
}

quote! {
#[doc(hidden)]
#[no_mangle]
Expand Down

0 comments on commit b7d7bbd

Please sign in to comment.