From 7ff013c5bbf45b3eccd2cafe2295d2b28c1fc7f9 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Thu, 29 Apr 2021 01:26:56 +0200 Subject: [PATCH] refactor(extensions): reintroduce declare_ops!() macro This implementation is both cleaner and more flexible than the original prototype in #9800 --- core/extensions.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++ core/lib.rs | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/extensions.rs b/core/extensions.rs index 134aab5d41c79b..7043ed484fa0a6 100644 --- a/core/extensions.rs +++ b/core/extensions.rs @@ -126,3 +126,65 @@ macro_rules! include_js_files { ] }; } + +// declare_ops! helps declare ops for an extension. +// Example: +// ``` +// declare_ops!( +// sync[ +// op_foo, +// op_bar, +// ], +// async[ +// op_write, +// op_read, +// ], +// ) +// ``` +#[macro_export] +macro_rules! declare_ops { + // A flattened group of async[] & sync[] subgroups + ($($wrapper:ident[$($opfn:expr,)+],)+) => { + vec![ + $(declare_ops!($wrapper[$($opfn,)+]),)+ + ].into_iter().flatten().collect() + }; + + // Async group + (async[$($opfn:expr,)+]) => { + vec![$(( + $crate::extensions::op_ident(stringify!($opfn)), + $crate::op_async($opfn), + ),)+] + }; + + // Sync group + (sync[$($opfn:expr,)+]) => { + vec![$(( + $crate::extensions::op_ident(stringify!($opfn)), + $crate::op_sync($opfn), + ),)+] + }; +} + +/// transforms a stringified identifier path into an op_name +/// it also enforces that all op_names must start with "op_" +/// ``` +/// stringify!(foo::op_bar) => "foo :: op_bar < X >" +/// op_ident(stringify!(foo::op_bar)) => "op_bar" +/// ``` +pub fn op_ident(ident_path: &'static str) -> &'static str { + let end = ident_path.rfind("::<").unwrap_or_else(|| ident_path.len()); + let ident_path = ident_path.get(0..end).unwrap(); + let start = ident_path.rfind("::").unwrap_or(0); + let name = ident_path.get(start..ident_path.len()).unwrap(); + + // Assert op_ prefix + assert!( + name.starts_with("op_"), + "Op '{}' missing 'op_' prefix", + name + ); + + name +} diff --git a/core/lib.rs b/core/lib.rs index 37055bcc8d7095..85d14d92c3e7de 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -3,7 +3,7 @@ mod async_cancel; mod async_cell; mod bindings; pub mod error; -mod extensions; +pub mod extensions; mod flags; mod gotham_state; mod module_specifier;