summaryrefslogtreecommitdiff
path: root/ops/lib.rs
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-05-12 19:13:25 +0200
committerGitHub <noreply@github.com>2022-05-12 19:13:25 +0200
commitc6063e390a0a005f14051493a50ab7db9fc02373 (patch)
tree6fded13f64a3d5698c7c5b3d9fff0e9264a5f33d /ops/lib.rs
parent5e6d3d42c7e0dc6173d726c8c7ebef8a94a6f65a (diff)
feat(ops): infallible / result-free ops (#14585)
Diffstat (limited to 'ops/lib.rs')
-rw-r--r--ops/lib.rs26
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 {