ephemeral_rollups_sdk_attribute_action/
lib.rs1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::parse::Parser;
5use syn::{parse_macro_input, Field, Fields, ItemStruct};
6
7#[proc_macro_attribute]
8pub fn action(_attr: TokenStream, item: TokenStream) -> TokenStream {
9 let input = parse_macro_input!(item as ItemStruct);
10
11 let name = &input.ident;
12 let attrs = &input.attrs; let expanded = if let Fields::Named(fields_named) = &input.fields {
14 let mut has_escrow_auth = false;
15 let mut has_escrow = false;
16
17 for field in &fields_named.named {
18 if let Some(ident) = &field.ident {
19 if ident == "escrow_auth" {
20 has_escrow_auth = true;
21 } else if ident == "escrow" {
22 has_escrow = true;
23 }
24 }
25 }
26
27 let mut new_fields = fields_named.named.clone();
28
29 if !has_escrow_auth {
30 new_fields.push(
31 Field::parse_named
32 .parse2(quote! {
33 pub escrow_auth: UncheckedAccount<'info>
35 })
36 .unwrap(),
37 );
38 }
39
40 if !has_escrow {
41 new_fields.push(
42 Field::parse_named
43 .parse2(quote! {
44 pub escrow: UncheckedAccount<'info>
46 })
47 .unwrap(),
48 );
49 }
50
51 quote! {
52 #(#attrs)*
53 pub struct #name<'info> {
54 #new_fields
55 }
56 }
57 } else {
58 quote! {
59 compile_error!("Action attribute can only be used with structs with named fields");
60 }
61 };
62
63 TokenStream::from(expanded)
64}