Detailed changes
@@ -15,8 +15,8 @@ use futures::{
TryStreamExt,
};
use gpui::{
- serde_json, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Model, SemanticVersion, Task,
- WeakModel,
+ actions, serde_json, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Model,
+ SemanticVersion, Task, WeakModel,
};
use lazy_static::lazy_static;
use parking_lot::RwLock;
@@ -70,14 +70,7 @@ pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894";
pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(100);
pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
-#[derive(Clone, Default, PartialEq, Deserialize)]
-pub struct SignIn;
-
-#[derive(Clone, Default, PartialEq, Deserialize)]
-pub struct SignOut;
-
-#[derive(Clone, Default, PartialEq, Deserialize)]
-pub struct Reconnect;
+actions!(SignIn, SignOut, Reconnect);
pub fn init_settings(cx: &mut AppContext) {
TelemetrySettings::register(cx);
@@ -4,7 +4,7 @@ use collections::{HashMap, HashSet};
use serde::Deserialize;
use std::any::{type_name, Any};
-pub trait Action: 'static {
+pub trait Action: std::fmt::Debug + 'static {
fn qualified_name() -> SharedString
where
Self: Sized;
@@ -17,12 +17,39 @@ pub trait Action: 'static {
fn as_any(&self) -> &dyn Any;
}
+// actions defines structs that can be used as actions.
+#[macro_export]
+macro_rules! actions {
+ () => {};
+
+ ( $name:ident ) => {
+ #[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq, $crate::serde::Deserialize)]
+ struct $name;
+ };
+
+ ( $name:ident { $($token:tt)* } ) => {
+ #[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq, $crate::serde::Deserialize)]
+ struct $name { $($token)* }
+ };
+
+ ( $name:ident, $($rest:tt)* ) => {
+ actions!($name);
+ actions!($($rest)*);
+ };
+
+ ( $name:ident { $($token:tt)* }, $($rest:tt)* ) => {
+ actions!($name { $($token)* });
+ actions!($($rest)*);
+ };
+}
+
impl<A> Action for A
where
- A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + 'static,
+ A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
{
fn qualified_name() -> SharedString {
- type_name::<A>().into()
+ // todo!() remove the 2 replacement when migration is done
+ type_name::<A>().replace("2::", "::").into()
}
fn build(params: Option<serde_json::Value>) -> Result<Box<dyn Action>>
@@ -292,6 +319,25 @@ mod tests {
use super::*;
use DispatchContextPredicate::*;
+ #[test]
+ fn test_actions_definition() {
+ {
+ actions!(A, B { field: i32 }, C, D, E, F {}, G);
+ }
+
+ {
+ actions!(
+ A,
+ B { field: i32 },
+ C,
+ D,
+ E,
+ F {},
+ G, // Don't wrap, test the trailing comma
+ );
+ }
+ }
+
#[test]
fn test_parse_context() {
let mut expected = DispatchContext::default();
@@ -1,3 +1,4 @@
+#[macro_use]
mod action;
mod app;
mod assets;
@@ -1233,8 +1233,6 @@ pub type KeyListener<V> = Box<
#[cfg(test)]
mod test {
- use serde_derive::Deserialize;
-
use crate::{
self as gpui, div, Div, FocusHandle, KeyBinding, Keystroke, ParentElement, Render,
StatefulInteraction, StatelessInteractive, TestAppContext, VisualContext,
@@ -1246,8 +1244,7 @@ mod test {
focus_handle: FocusHandle,
}
- #[derive(PartialEq, Clone, Default, Deserialize)]
- struct TestAction;
+ actions!(TestAction);
impl Render for TestView {
type Element = Div<Self, StatefulInteraction<Self>>;
@@ -1,18 +1,10 @@
use gpui::{
- div, Div, FocusEnabled, Focusable, KeyBinding, ParentElement, Render, StatefulInteraction,
- StatelessInteractive, Styled, View, VisualContext, WindowContext,
+ actions, div, Div, FocusEnabled, Focusable, KeyBinding, ParentElement, Render,
+ StatefulInteraction, StatelessInteractive, Styled, View, VisualContext, WindowContext,
};
-use serde::Deserialize;
use theme2::ActiveTheme;
-#[derive(Clone, Default, PartialEq, Deserialize)]
-struct ActionA;
-
-#[derive(Clone, Default, PartialEq, Deserialize)]
-struct ActionB;
-
-#[derive(Clone, Default, PartialEq, Deserialize)]
-struct ActionC;
+actions!(ActionA, ActionB, ActionC);
pub struct FocusStory {}