diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-05-12 19:13:25 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-12 19:13:25 +0200 |
commit | c6063e390a0a005f14051493a50ab7db9fc02373 (patch) | |
tree | 6fded13f64a3d5698c7c5b3d9fff0e9264a5f33d /ops/lib.rs | |
parent | 5e6d3d42c7e0dc6173d726c8c7ebef8a94a6f65a (diff) |
feat(ops): infallible / result-free ops (#14585)
Diffstat (limited to 'ops/lib.rs')
-rw-r--r-- | ops/lib.rs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/ops/lib.rs b/ops/lib.rs index a5e5ce51b..c190a1c4d 100644 --- a/ops/lib.rs +++ b/ops/lib.rs @@ -154,6 +154,11 @@ fn codegen_v8_async( let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 1); let type_params = &f.sig.generics.params; + let result_wrapper = match is_result(&f.sig.output) { + true => quote! {}, + false => quote! { let result = Ok(result); }, + }; + quote! { use #core::futures::FutureExt; // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime @@ -189,6 +194,7 @@ fn codegen_v8_async( #core::_ops::queue_async_op(scope, async move { let result = Self::call::<#type_params>(#args_head #args_tail).await; + #result_wrapper (promise_id, op_id, #core::_ops::to_op_result(get_class, result)) }); } @@ -325,7 +331,14 @@ fn codegen_sync_ret( } }; + let result_wrapper = match is_result(&**ret_type) { + true => quote! {}, + false => quote! { let result = Ok(result); }, + }; + quote! { + #result_wrapper + match result { Ok(v) => { #ok_block @@ -338,6 +351,19 @@ fn codegen_sync_ret( } } +fn is_result(ty: impl ToTokens) -> bool { + let tokens = tokens(ty); + if tokens.trim_start_matches("-> ").starts_with("Result <") { + return true; + } + // Detect `io::Result<...>`, `anyhow::Result<...>`, etc... + // i.e: Result aliases/shorthands which are unfortunately "opaque" at macro-time + match tokens.find(":: Result <") { + Some(idx) => !tokens.split_at(idx).0.contains('<'), + None => false, + } +} + /// Detects if a type is of the form Result<(), Err> fn is_unit_result(ty: &syn::Type) -> bool { let path = match ty { |