浏览代码

Refactor `WebEventExt` (#2707)

* Create WebEventExt::try_as_web_event and refactor
* Inline and adjust error message
* Inline downcast methods
Matt Hunzinger 11 月之前
父节点
当前提交
4bf71111c8

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_ref().as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_ref().as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         HasDragData::as_any(&*self.inner).downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
packages/html/src/events/keyboard.rs

@@ -83,6 +83,7 @@ impl KeyboardData {
     }
 
     /// Downcast this KeyboardData to a concrete type.
+    #[inline(always)]
     pub fn downcast<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 2 - 1
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }
@@ -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");
     ///             }
     ///         }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 2 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }
@@ -213,6 +214,7 @@ impl TouchPoint {
     }
 
     /// Downcast this event to a concrete event type
+    #[inline(always)]
     pub fn downcast<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         self.inner.as_any().downcast_ref::<T>()
     }

+ 1 - 0
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<T: 'static>(&self) -> Option<&T> {
         HasWheelData::as_any(&*self.inner).downcast_ref::<T>()
     }

+ 53 - 41
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<E> {
-    /// 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::<E>()
+            )
+        })
+    }
 }
 
 impl WebEventExt<web_sys::AnimationEvent> 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::<web_sys::AnimationEvent>()
-            .expect("event should be a WebAnimationEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> 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::<web_sys::Event>()
-            .expect("event should be a web_sys::Event")
     }
 }
 
 impl WebEventExt<web_sys::CompositionEvent> 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::<web_sys::CompositionEvent>()
-            .expect("event should be a WebCompositionEvent")
     }
 }
 
 impl WebEventExt<web_sys::MouseEvent> for dioxus_html::DragData {
-    fn web_event(&self) -> &web_sys::MouseEvent {
-        &self
-            .downcast::<WebDragData>()
-            .expect("event should be a WebMouseEvent")
-            .raw
+    #[inline(always)]
+    fn try_as_web_event(&self) -> Option<&web_sys::MouseEvent> {
+        self.downcast::<WebDragData>().map(|data| &data.raw)
     }
 }
 
 impl WebEventExt<web_sys::FocusEvent> 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::<web_sys::FocusEvent>()
-            .expect("event should be a WebFocusEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> 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::<web_sys::Event>()
-            .expect("event should be a WebFormData")
     }
 }
 
 impl WebEventExt<WebImageEvent> for dioxus_html::ImageData {
-    fn web_event(&self) -> &WebImageEvent {
+    #[inline(always)]
+    fn try_as_web_event(&self) -> Option<&WebImageEvent> {
         self.downcast::<WebImageEvent>()
-            .expect("event should be a WebImageEvent")
     }
 }
 
 impl WebEventExt<web_sys::KeyboardEvent> 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::<web_sys::KeyboardEvent>()
-            .expect("event should be a WebKeyboardEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> 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::<web_sys::Event>()
-            .expect("event should be a WebMediaEvent")
     }
 }
 
 impl WebEventExt<web_sys::Element> for MountedData {
-    fn web_event(&self) -> &web_sys::Element {
+    #[inline(always)]
+    fn try_as_web_event(&self) -> Option<&web_sys::Element> {
         self.downcast::<web_sys::Element>()
-            .expect("event should be a web_sys::Element")
     }
 }
 
 impl WebEventExt<web_sys::MouseEvent> 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::<web_sys::MouseEvent>()
-            .expect("event should be a WebMouseEvent")
     }
 }
 
 impl WebEventExt<web_sys::PointerEvent> 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::<web_sys::PointerEvent>()
-            .expect("event should be a WebPointerEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> for ScrollData {
-    fn web_event(&self) -> &web_sys::Event {
+    #[inline(always)]
+    fn try_as_web_event(&self) -> Option<&web_sys::Event> {
         self.downcast::<web_sys::Event>()
-            .expect("event should be a WebScrollEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> 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::<web_sys::Event>()
-            .expect("event should be a WebSelectionEvent")
     }
 }
 
 impl WebEventExt<web_sys::Event> 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::<web_sys::Event>()
-            .expect("event should be a WebToggleEvent")
     }
 }
 
 impl WebEventExt<web_sys::TouchEvent> 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::<web_sys::TouchEvent>()
-            .expect("event should be a WebTouchEvent")
     }
 }
 
 impl WebEventExt<web_sys::TransitionEvent> 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::<web_sys::TransitionEvent>()
-            .expect("event should be a WebTransitionEvent")
     }
 }
 
 impl WebEventExt<web_sys::WheelEvent> 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::<web_sys::WheelEvent>()
-            .expect("event should be a WebWheelEvent")
     }
 }