action.rs

 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}