The only difference between the two is function signatures and how to access the event. The bulk of the event_handler! macro remains in event_handler_body!, with specific implementations for objects and namespaces.
YKBMKWDPOQKACONKDMURG76BE7N7DA4HLM57V7ARYZPQOHDFCE5QC event_handler!("workspace","onDidChangeTextDocument",on_did_change_text_document(TextDocumentChangeEvent));event_handler!("workspace","onDidChangeWorkspaceFolders",on_did_change_workspace_folders(WorkspaceFoldersChangeEvent));
namespace_event_handler! {"workspace" {"onDidChangeTextDocument": on_did_change_text_document(TextDocumentChangeEvent);"onDidChangeWorkspaceFolders": on_did_change_workspace_folders(WorkspaceFoldersChangeEvent);}}
event_handler!("window","onDidChangeTextEditorSelection",on_did_change_text_editor_selections(TextEditorSelectionChangeEvent));event_handler!("window","onDidChangeVisibleTextEditors",on_did_change_visible_text_editors(Vec<TextEditor>));
namespace_event_handler! {"window" {"onDidChangeTextEditorSelection": on_did_change_text_editor_selections(TextEditorSelectionChangeEvent);"onDidChangeVisibleTextEditors": on_did_change_visible_text_editors(Vec<TextEditor>);}}
macro_rules! object_event_handler {($interface_name:ident {$($function_js_name:literal: $function_rust_name:ident($event_type:ty);)*}) => {impl<'env> $interface_name<'env> {$(pub fn $function_rust_name<F>(&self,env: &napi::Env,handler: F,// TODO: generic errors) -> Result<(), napi::Error>whereF: for<'function_context> Fn(&'function_context napi::Env,$event_type,) -> Result<(), napi::Error>+ std::panic::RefUnwindSafe+ 'static,{crate::vscode_sys::macros::event_handler_body! {env,handler,self.inner,$function_js_name,$function_rust_name($event_type)}})*}};}pub(crate) use object_event_handler;
macro_rules! namespace_event_handler {($namespace:literal {$($function_js_name:literal: $function_rust_name:ident($event_type:ty);)*}) => {$(pub fn $function_rust_name<F>(env: &napi::Env,handler: F,// TODO: generic errors) -> Result<(), napi::Error>whereF: for<'function_context> Fn(&'function_context napi::Env,$event_type,) -> Result<(), napi::Error>+ std::panic::RefUnwindSafe+ 'static,{let vscode_object = super::VscodeContext::vscode(env)?;let event_container: bindgen_prelude::Object =vscode_object.get_named_property($namespace)?;crate::vscode_sys::macros::event_handler_body! {env,handler,event_container,$function_js_name,$function_rust_name($event_type)}})*};}pub(crate) use namespace_event_handler;
pub fn $function_rust_name<F>(env: &napi::Env,handler: F,// TODO: generic errors) -> Result<(), napi::Error>whereF: for<'function_context> Fn(&'function_context napi::Env,$event_type,) -> Result<(), napi::Error>+ std::panic::RefUnwindSafe+ 'static,{let extension_context = super::VscodeContext::extension_context(env)?;let mut subscriptions: bindgen_prelude::Array =extension_context.get_named_property("subscriptions")?;
let extension_context = crate::vscode_sys::VscodeContext::extension_context($env)?;let mut subscriptions: bindgen_prelude::Array =extension_context.get_named_property("subscriptions")?;let event_creator: bindgen_prelude::Function<bindgen_prelude::Function<$event_type, ()>,// TODO: disposablebindgen_prelude::Object,> = $event_container.get_named_property($function_js_name)?;let event_handler_fn: bindgen_prelude::Function<$event_type, ()> = $env.create_function_from_closure($function_js_name, move |function_context| {let parent_span = tracing::span!(tracing::Level::TRACE, "event_handler");let _entered_span = parent_span.enter();
let vscode_object = super::VscodeContext::vscode(env)?;let namespace: bindgen_prelude::Object =vscode_object.get_named_property($namespace)?;let event_creator: bindgen_prelude::Function<bindgen_prelude::Function<$event_type, ()>,// TODO: disposablebindgen_prelude::Object,> = namespace.get_named_property($function_js_name)?;let event_handler_fn: bindgen_prelude::Function<$event_type, ()> = env.create_function_from_closure($function_js_name, move |function_context| {let parent_span = tracing::span!(tracing::Level::TRACE, "event_handler");let _entered_span = parent_span.enter();
let event = match function_context.args::<($event_type,)>() {Ok((event,)) => event,Err(error) => {tracing::error!(message = "Invalid arguments provided to event handler",event_handler = $function_js_name,?error);
let event = match function_context.args::<($event_type,)>() {Ok((event,)) => event,
return Err(napi::Error::from_reason("Invalid arguments provided to event handler",));}};match std::panic::catch_unwind(|| $handler(function_context.env, event)) {Ok(handler_result) => match handler_result {Ok(result) => Ok(result),
match std::panic::catch_unwind(|| handler(function_context.env, event)) {Ok(handler_result) => match handler_result {Ok(result) => Ok(result),Err(error) => {tracing::error!(message = "Event handler returned an error",event_handler = $function_js_name,?error);Err(napi::Error::from_reason("Event handler returned an error"))}},Err(panic_payload) => {tracing::error!(message = "Event handler panicked",event_handler = $function_js_name,?panic_payload);Err(napi::Error::from_reason("Event handler panicked"))}
Err(napi::Error::from_reason("Event handler panicked"))
let handler_subscription: bindgen_prelude::Object =event_creator.call(event_handler_fn)?;subscriptions.insert(handler_subscription)?;
let handler_subscription: bindgen_prelude::Object = event_creator.call(event_handler_fn)?;subscriptions.insert(handler_subscription)?;