Re-introduce a macro for defining actions for ease of use

Co-Authored-By: Piotr Osiewicz <piotr@zed.dev>
Co-Authored-By: Conrad Irwin <conrad@zed.dev>
This commit is contained in:
Julia 2023-11-07 11:00:30 -05:00
parent 2e43015664
commit 643146d768
5 changed files with 57 additions and 28 deletions

View file

@ -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);

View file

@ -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();

View file

@ -1,3 +1,4 @@
#[macro_use]
mod action;
mod app;
mod assets;

View file

@ -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>>;

View file

@ -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 {}