ephemeral_rollups_sdk_attribute_commit/
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 commit(_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_magic_program = false;
15 let mut has_magic_context = false;
16
17 for field in &fields_named.named {
18 if let Some(ident) = &field.ident {
19 if ident == "magic_program" {
20 has_magic_program = true;
21 } else if ident == "magic_context" {
22 has_magic_context = true;
23 }
24 }
25 }
26
27 let mut new_fields = fields_named.named.clone();
28
29 if !has_magic_program {
30 new_fields.push(
31 Field::parse_named
32 .parse2(quote! {
33 pub magic_program: Program<'info, ::ephemeral_rollups_sdk::anchor::MagicProgram>
34 })
35 .unwrap(),
36 );
37 }
38
39 if !has_magic_context {
40 new_fields.push(
41 Field::parse_named
42 .parse2(quote! {
43 #[account(mut, address = ::ephemeral_rollups_sdk::consts::MAGIC_CONTEXT_ID)]
44 pub magic_context: AccountInfo<'info>
46 })
47 .unwrap(),
48 );
49 }
50
51 quote! {
52 use ::ephemeral_rollups_sdk::anchor::MagicProgram;
53 #(#attrs)*
54 pub struct #name<'info> {
55 #new_fields
56 }
57 }
58 } else {
59 quote! {
60 compile_error!("Commit attribute can only be used with structs with named fields");
61 }
62 };
63
64 TokenStream::from(expanded)
65}