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:
parent
2e43015664
commit
643146d768
5 changed files with 57 additions and 28 deletions
|
@ -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 {}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue