1// Input:
2//
3// #[action]
4// struct Foo {
5// bar: String,
6// }
7
8// Output:
9//
10// #[gpui::register_action]
11// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
12// struct Foo {
13// bar: String,
14// }
15
16use proc_macro::TokenStream;
17use quote::quote;
18use syn::{parse_macro_input, DeriveInput};
19
20pub fn action(_attr: TokenStream, item: TokenStream) -> TokenStream {
21 let input = parse_macro_input!(item as DeriveInput);
22 let name = &input.ident;
23 let attrs = input
24 .attrs
25 .into_iter()
26 .filter(|attr| !attr.path.is_ident("action"))
27 .collect::<Vec<_>>();
28
29 let attributes = quote! {
30 #[gpui::register_action]
31 #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
32 #(#attrs)*
33 };
34 let visibility = input.vis;
35
36 let output = match input.data {
37 syn::Data::Struct(ref struct_data) => {
38 let fields = &struct_data.fields;
39 quote! {
40 #attributes
41 #visibility struct #name #fields
42 }
43 }
44 syn::Data::Enum(ref enum_data) => {
45 let variants = &enum_data.variants;
46 quote! {
47 #attributes
48 #visibility enum #name { #variants }
49 }
50 }
51 _ => panic!("Expected a struct or an enum."),
52 };
53
54 TokenStream::from(output)
55}