Simplify actions macro.
This commit is contained in:
parent
fdc9ea7f9b
commit
2a55b0dbfb
3 changed files with 45 additions and 25 deletions
|
@ -137,7 +137,8 @@ pub fn all_action_names() -> MappedRwLockReadGuard<'static, [SharedString]> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// actions defines structs that can be used as actions.
|
/// Defines unit structs that can be used as actions.
|
||||||
|
/// To use more complex data types as actions, annotate your type with the #[action] macro.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! actions {
|
macro_rules! actions {
|
||||||
() => {};
|
() => {};
|
||||||
|
@ -148,21 +149,10 @@ macro_rules! actions {
|
||||||
pub struct $name;
|
pub struct $name;
|
||||||
};
|
};
|
||||||
|
|
||||||
( $name:ident { $($token:tt)* } ) => {
|
|
||||||
#[gpui::register_action]
|
|
||||||
#[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq, $crate::serde::Deserialize)]
|
|
||||||
pub struct $name { $($token)* }
|
|
||||||
};
|
|
||||||
|
|
||||||
( $name:ident, $($rest:tt)* ) => {
|
( $name:ident, $($rest:tt)* ) => {
|
||||||
actions!($name);
|
actions!($name);
|
||||||
actions!($($rest)*);
|
actions!($($rest)*);
|
||||||
};
|
};
|
||||||
|
|
||||||
( $name:ident { $($token:tt)* }, $($rest:tt)* ) => {
|
|
||||||
actions!($name { $($token)* });
|
|
||||||
actions!($($rest)*);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
|
@ -408,17 +398,17 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_actions_definition() {
|
fn test_actions_definition() {
|
||||||
{
|
{
|
||||||
actions!(A, B { field: i32 }, C, D, E, F {}, G);
|
actions!(A, B, C, D, E, F, G);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
actions!(
|
actions!(
|
||||||
A,
|
A,
|
||||||
B { field: i32 },
|
B,
|
||||||
C,
|
C,
|
||||||
D,
|
D,
|
||||||
E,
|
E,
|
||||||
F {},
|
F,
|
||||||
G, // Don't wrap, test the trailing comma
|
G, // Don't wrap, test the trailing comma
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
// Input:
|
// Input:
|
||||||
//
|
//
|
||||||
// #[action]
|
// #[action]
|
||||||
// struct Foo {}
|
// struct Foo {
|
||||||
|
// bar: String,
|
||||||
|
// }
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
//
|
//
|
||||||
// #[gpui::register_action]
|
// #[gpui::register_action]
|
||||||
// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
|
// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
|
||||||
// struct Foo {}
|
// struct Foo {
|
||||||
|
// bar: String,
|
||||||
|
// }
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
@ -16,15 +20,35 @@ use syn::{parse_macro_input, DeriveInput};
|
||||||
pub fn action(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn action(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(item as DeriveInput);
|
let input = parse_macro_input!(item as DeriveInput);
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
let data = &input.data;
|
let attrs = input
|
||||||
|
.attrs
|
||||||
|
.into_iter()
|
||||||
|
.filter(|attr| !attr.path.is_ident("action"))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let data_tokens = quote! { #data }.into();
|
let attributes = quote! {
|
||||||
|
|
||||||
let expanded = quote! {
|
|
||||||
#[gpui::register_action]
|
#[gpui::register_action]
|
||||||
#[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
|
#[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
|
||||||
struct #name { #data }
|
#(#attrs)*
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenStream::from(expanded)
|
let output = match input.data {
|
||||||
|
syn::Data::Struct(ref struct_data) => {
|
||||||
|
let fields = &struct_data.fields;
|
||||||
|
quote! {
|
||||||
|
#attributes
|
||||||
|
struct #name { #fields }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syn::Data::Enum(ref enum_data) => {
|
||||||
|
let variants = &enum_data.variants;
|
||||||
|
quote! {
|
||||||
|
#attributes
|
||||||
|
enum #name { #variants }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("Expected a struct or an enum."),
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(output)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
use proc_macro::TokenStream;
|
mod action;
|
||||||
|
|
||||||
mod derive_component;
|
mod derive_component;
|
||||||
mod register_action;
|
mod register_action;
|
||||||
mod style_helpers;
|
mod style_helpers;
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn style_helpers(args: TokenStream) -> TokenStream {
|
pub fn style_helpers(args: TokenStream) -> TokenStream {
|
||||||
style_helpers::style_helpers(args)
|
style_helpers::style_helpers(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn action(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
action::action(attr, item)
|
||||||
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn register_action(attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn register_action(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
register_action::register_action(attr, item)
|
register_action::register_action(attr, item)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue