Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/action.rs             | 22 +++++++++++
crates/gpui3/src/keymap/binding.rs     |  2 
crates/storybook2/src/stories/focus.rs | 53 ++-------------------------
3 files changed, 27 insertions(+), 50 deletions(-)

Detailed changes

crates/gpui3/src/action.rs 🔗

@@ -4,11 +4,31 @@ use collections::{HashMap, HashSet};
 use std::any::Any;
 
 pub trait Action: Any + Send + Sync {
-    fn eq(&self, action: &dyn Action) -> bool;
+    fn partial_eq(&self, action: &dyn Action) -> bool;
     fn boxed_clone(&self) -> Box<dyn Action>;
     fn as_any(&self) -> &dyn Any;
 }
 
+impl<T> Action for T
+where
+    T: Any + PartialEq + Clone + Send + Sync,
+{
+    fn partial_eq(&self, action: &dyn Action) -> bool {
+        action
+            .as_any()
+            .downcast_ref::<Self>()
+            .map_or(false, |a| self == a)
+    }
+
+    fn boxed_clone(&self) -> Box<dyn Action> {
+        Box::new(self.clone())
+    }
+
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+}
+
 #[derive(Clone, Debug, Default, Eq, PartialEq)]
 pub struct DispatchContext {
     set: HashSet<SharedString>,

crates/gpui3/src/keymap/binding.rs 🔗

@@ -63,7 +63,7 @@ impl KeyBinding {
         action: &dyn Action,
         contexts: &[&DispatchContext],
     ) -> Option<SmallVec<[Keystroke; 2]>> {
-        if self.action.eq(action) && self.matches_context(contexts) {
+        if self.action.partial_eq(action) && self.matches_context(contexts) {
             Some(self.keystrokes.clone())
         } else {
             None

crates/storybook2/src/stories/focus.rs 🔗

@@ -1,61 +1,18 @@
 use crate::themes::rose_pine;
 use gpui3::{
-    div, view, Action, Context, Focusable, KeyBinding, ParentElement, StatelessInteractive, Styled,
-    View, WindowContext,
+    div, view, Context, Focusable, KeyBinding, ParentElement, StatelessInteractive, Styled, View,
+    WindowContext,
 };
-use std::any::Any;
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 struct ActionA;
 
-impl Action for ActionA {
-    fn eq(&self, action: &dyn Action) -> bool {
-        action.as_any().downcast_ref::<Self>().is_some()
-    }
-
-    fn boxed_clone(&self) -> Box<dyn Action> {
-        Box::new(self.clone())
-    }
-
-    fn as_any(&self) -> &dyn Any {
-        self
-    }
-}
-
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 struct ActionB;
 
-impl Action for ActionB {
-    fn eq(&self, action: &dyn Action) -> bool {
-        action.as_any().downcast_ref::<Self>().is_some()
-    }
-
-    fn boxed_clone(&self) -> Box<dyn Action> {
-        Box::new(self.clone())
-    }
-
-    fn as_any(&self) -> &dyn Any {
-        self
-    }
-}
-
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 struct ActionC;
 
-impl Action for ActionC {
-    fn eq(&self, action: &dyn Action) -> bool {
-        action.as_any().downcast_ref::<Self>().is_some()
-    }
-
-    fn boxed_clone(&self) -> Box<dyn Action> {
-        Box::new(self.clone())
-    }
-
-    fn as_any(&self) -> &dyn Any {
-        self
-    }
-}
-
 pub struct FocusStory {
     text: View<()>,
 }