From 4bf71111c8c0f6c854e66029b30dab494c43fbe2 Mon Sep 17 00:00:00 2001 From: Matt Hunzinger Date: Wed, 31 Jul 2024 16:01:25 -0400 Subject: [PATCH] Refactor `WebEventExt` (#2707) * Create WebEventExt::try_as_web_event and refactor * Inline and adjust error message * Inline downcast methods --- packages/html/src/events/animation.rs | 1 + packages/html/src/events/clipboard.rs | 1 + packages/html/src/events/drag.rs | 1 + packages/html/src/events/focus.rs | 1 + packages/html/src/events/form.rs | 1 + packages/html/src/events/keyboard.rs | 1 + packages/html/src/events/media.rs | 1 + packages/html/src/events/mounted.rs | 3 +- packages/html/src/events/mouse.rs | 1 + packages/html/src/events/pointer.rs | 1 + packages/html/src/events/scroll.rs | 1 + packages/html/src/events/selection.rs | 1 + packages/html/src/events/toggle.rs | 1 + packages/html/src/events/touch.rs | 2 + packages/html/src/events/transition.rs | 1 + packages/html/src/events/wheel.rs | 1 + packages/web/src/event.rs | 94 +++++++++++++++----------- 17 files changed, 71 insertions(+), 42 deletions(-) diff --git a/packages/html/src/events/animation.rs b/packages/html/src/events/animation.rs index 26db06f9d..23f621912 100644 --- a/packages/html/src/events/animation.rs +++ b/packages/html/src/events/animation.rs @@ -30,6 +30,7 @@ impl AnimationData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_ref().as_any().downcast_ref::() } diff --git a/packages/html/src/events/clipboard.rs b/packages/html/src/events/clipboard.rs index c0180c728..265a747e9 100644 --- a/packages/html/src/events/clipboard.rs +++ b/packages/html/src/events/clipboard.rs @@ -33,6 +33,7 @@ impl ClipboardData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_ref().as_any().downcast_ref::() } diff --git a/packages/html/src/events/drag.rs b/packages/html/src/events/drag.rs index 32ed4acef..18df85c44 100644 --- a/packages/html/src/events/drag.rs +++ b/packages/html/src/events/drag.rs @@ -52,6 +52,7 @@ impl DragData { } /// Downcast this event data to a specific type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { HasDragData::as_any(&*self.inner).downcast_ref::() } diff --git a/packages/html/src/events/focus.rs b/packages/html/src/events/focus.rs index f121feb7b..c5571e7ff 100644 --- a/packages/html/src/events/focus.rs +++ b/packages/html/src/events/focus.rs @@ -33,6 +33,7 @@ impl FocusData { } /// Downcast this event data to a specific type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/form.rs b/packages/html/src/events/form.rs index e5aab2a44..170adef7e 100644 --- a/packages/html/src/events/form.rs +++ b/packages/html/src/events/form.rs @@ -111,6 +111,7 @@ impl FormData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/keyboard.rs b/packages/html/src/events/keyboard.rs index dbb7ea281..172991f97 100644 --- a/packages/html/src/events/keyboard.rs +++ b/packages/html/src/events/keyboard.rs @@ -83,6 +83,7 @@ impl KeyboardData { } /// Downcast this KeyboardData to a concrete type. + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/media.rs b/packages/html/src/events/media.rs index 7f3180cf7..f7ea3d6b7 100644 --- a/packages/html/src/events/media.rs +++ b/packages/html/src/events/media.rs @@ -32,6 +32,7 @@ impl MediaData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/mounted.rs b/packages/html/src/events/mounted.rs index c0e220597..cccf53c7a 100644 --- a/packages/html/src/events/mounted.rs +++ b/packages/html/src/events/mounted.rs @@ -121,6 +121,7 @@ impl MountedData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } @@ -186,7 +187,7 @@ impl_event! [ /// id: "some-id", /// onmounted: move |element| { /// // You can use the web_event trait to downcast the element to a web specific event. For the mounted event, this will be a web_sys::Element - /// let web_sys_element = element.web_event(); + /// let web_sys_element = element.as_web_event(); /// assert_eq!(web_sys_element.id(), "some-id"); /// } /// } diff --git a/packages/html/src/events/mouse.rs b/packages/html/src/events/mouse.rs index f6b3d14a9..ed50c8ae7 100644 --- a/packages/html/src/events/mouse.rs +++ b/packages/html/src/events/mouse.rs @@ -113,6 +113,7 @@ impl MouseData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/pointer.rs b/packages/html/src/events/pointer.rs index 9556502d3..312f14879 100644 --- a/packages/html/src/events/pointer.rs +++ b/packages/html/src/events/pointer.rs @@ -17,6 +17,7 @@ impl PointerData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/scroll.rs b/packages/html/src/events/scroll.rs index 3693cc144..0ee2a2de7 100644 --- a/packages/html/src/events/scroll.rs +++ b/packages/html/src/events/scroll.rs @@ -21,6 +21,7 @@ impl ScrollData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/selection.rs b/packages/html/src/events/selection.rs index 30c3d9bf0..0f23a4ad2 100644 --- a/packages/html/src/events/selection.rs +++ b/packages/html/src/events/selection.rs @@ -15,6 +15,7 @@ impl SelectionData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/toggle.rs b/packages/html/src/events/toggle.rs index e929a6a64..c8d352ed9 100644 --- a/packages/html/src/events/toggle.rs +++ b/packages/html/src/events/toggle.rs @@ -33,6 +33,7 @@ impl ToggleData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/touch.rs b/packages/html/src/events/touch.rs index b30ace17c..999c9717b 100644 --- a/packages/html/src/events/touch.rs +++ b/packages/html/src/events/touch.rs @@ -56,6 +56,7 @@ impl TouchData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } @@ -213,6 +214,7 @@ impl TouchPoint { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/transition.rs b/packages/html/src/events/transition.rs index 4e680d650..18863318d 100644 --- a/packages/html/src/events/transition.rs +++ b/packages/html/src/events/transition.rs @@ -39,6 +39,7 @@ impl TransitionData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() } diff --git a/packages/html/src/events/wheel.rs b/packages/html/src/events/wheel.rs index f8dc38d94..0a51be817 100644 --- a/packages/html/src/events/wheel.rs +++ b/packages/html/src/events/wheel.rs @@ -54,6 +54,7 @@ impl WheelData { } /// Downcast this event to a concrete event type + #[inline(always)] pub fn downcast(&self) -> Option<&T> { HasWheelData::as_any(&*self.inner).downcast_ref::() } diff --git a/packages/web/src/event.rs b/packages/web/src/event.rs index 28f04fadb..6b1e9d16a 100644 --- a/packages/web/src/event.rs +++ b/packages/web/src/event.rs @@ -157,135 +157,147 @@ impl HtmlEventConverter for WebEventConverter { /// A extension trait for web-sys events that provides a way to get the event as a web-sys event. pub trait WebEventExt { - /// Get the event as a web-sys event. - fn web_event(&self) -> &E; + /// Try to downcast this event as a `web-sys` event. + fn try_as_web_event(&self) -> Option<&E>; + + /// Downcast this event as a `web-sys` event. + #[inline(always)] + fn as_web_event(&self) -> &E + where + E: 'static, + { + self.try_as_web_event().unwrap_or_else(|| { + panic!( + "Error downcasting to `web-sys`, event should be a {}.", + std::any::type_name::() + ) + }) + } } impl WebEventExt for dioxus_html::AnimationData { - fn web_event(&self) -> &web_sys::AnimationEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::AnimationEvent> { self.downcast::() - .expect("event should be a WebAnimationEvent") } } impl WebEventExt for dioxus_html::ClipboardData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a web_sys::Event") } } impl WebEventExt for dioxus_html::CompositionData { - fn web_event(&self) -> &web_sys::CompositionEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::CompositionEvent> { self.downcast::() - .expect("event should be a WebCompositionEvent") } } impl WebEventExt for dioxus_html::DragData { - fn web_event(&self) -> &web_sys::MouseEvent { - &self - .downcast::() - .expect("event should be a WebMouseEvent") - .raw + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::MouseEvent> { + self.downcast::().map(|data| &data.raw) } } impl WebEventExt for dioxus_html::FocusData { - fn web_event(&self) -> &web_sys::FocusEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::FocusEvent> { self.downcast::() - .expect("event should be a WebFocusEvent") } } impl WebEventExt for dioxus_html::FormData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a WebFormData") } } impl WebEventExt for dioxus_html::ImageData { - fn web_event(&self) -> &WebImageEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&WebImageEvent> { self.downcast::() - .expect("event should be a WebImageEvent") } } impl WebEventExt for dioxus_html::KeyboardData { - fn web_event(&self) -> &web_sys::KeyboardEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::KeyboardEvent> { self.downcast::() - .expect("event should be a WebKeyboardEvent") } } impl WebEventExt for dioxus_html::MediaData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a WebMediaEvent") } } impl WebEventExt for MountedData { - fn web_event(&self) -> &web_sys::Element { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Element> { self.downcast::() - .expect("event should be a web_sys::Element") } } impl WebEventExt for dioxus_html::MouseData { - fn web_event(&self) -> &web_sys::MouseEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::MouseEvent> { self.downcast::() - .expect("event should be a WebMouseEvent") } } impl WebEventExt for dioxus_html::PointerData { - fn web_event(&self) -> &web_sys::PointerEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::PointerEvent> { self.downcast::() - .expect("event should be a WebPointerEvent") } } impl WebEventExt for ScrollData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a WebScrollEvent") } } impl WebEventExt for dioxus_html::SelectionData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a WebSelectionEvent") } } impl WebEventExt for dioxus_html::ToggleData { - fn web_event(&self) -> &web_sys::Event { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::Event> { self.downcast::() - .expect("event should be a WebToggleEvent") } } impl WebEventExt for dioxus_html::TouchData { - fn web_event(&self) -> &web_sys::TouchEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::TouchEvent> { self.downcast::() - .expect("event should be a WebTouchEvent") } } impl WebEventExt for dioxus_html::TransitionData { - fn web_event(&self) -> &web_sys::TransitionEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::TransitionEvent> { self.downcast::() - .expect("event should be a WebTransitionEvent") } } impl WebEventExt for dioxus_html::WheelData { - fn web_event(&self) -> &web_sys::WheelEvent { + #[inline(always)] + fn try_as_web_event(&self) -> Option<&web_sys::WheelEvent> { self.downcast::() - .expect("event should be a WebWheelEvent") } }