Browse Source

:sparkles: Simplify component_deserialize macro (#34)

* :sparkles: Simplify component_deserialize macro

* :sparkles: Add `new` fn to init components

* :sparkles: Use a struct as input to the new fn
Gabriele Picco 1 year ago
parent
commit
c8395cc68a

+ 1 - 2
crates/bolt-lang/attribute/component-deserialize/src/lib.rs

@@ -18,8 +18,7 @@ pub fn component_deserialize(_attr: TokenStream, item: TokenStream) -> TokenStre
     let mut input = parse_macro_input!(item as DeriveInput);
 
     // Add the AnchorDeserialize and AnchorSerialize derives to the struct
-    let additional_derives: Attribute =
-        syn::parse_quote! { #[derive(bolt_lang::AnchorDeserialize, bolt_lang::AnchorSerialize)] };
+    let additional_derives: Attribute = syn::parse_quote! { #[derive(bolt_lang::InitSpace, bolt_lang::AnchorDeserialize, bolt_lang::AnchorSerialize, Clone, Copy)] };
     input.attrs.push(additional_derives);
 
     let name = &input.ident.clone();

+ 52 - 1
crates/bolt-lang/attribute/component/src/lib.rs

@@ -1,8 +1,10 @@
-use bolt_utils::add_bolt_metadata;
 use proc_macro::TokenStream;
+
 use quote::quote;
 use syn::{parse_macro_input, parse_quote, Attribute, DeriveInput, Lit, Meta, NestedMeta};
 
+use bolt_utils::add_bolt_metadata;
+
 /// This Component attribute is used to automatically generate the seed and size functions
 ///
 /// The component_id can be used to define the seed used to generate the PDA which stores the component data.
@@ -58,6 +60,10 @@ pub fn component(attr: TokenStream, item: TokenStream) -> TokenStream {
     let additional_derives: Attribute = parse_quote! { #[derive(InitSpace)] };
     input.attrs.push(additional_derives);
 
+    let new_fn = define_new_fn(&input);
+    // print new_fn
+    println!("{:?}", new_fn);
+
     add_bolt_metadata(&mut input);
 
     let name = &input.ident;
@@ -76,6 +82,8 @@ pub fn component(attr: TokenStream, item: TokenStream) -> TokenStream {
         #additional_macro
         #input
 
+        #new_fn
+
         #[automatically_derived]
         impl ComponentTraits for #name {
             fn seed() -> &'static [u8] {
@@ -86,6 +94,49 @@ pub fn component(attr: TokenStream, item: TokenStream) -> TokenStream {
                 8 + <#name>::INIT_SPACE
             }
         }
+
     };
     expanded.into()
 }
+
+/// Create a fn `new` to initialize the struct without bolt_metadata field
+fn define_new_fn(input: &DeriveInput) -> proc_macro2::TokenStream {
+    let struct_name = &input.ident;
+    let init_struct_name = syn::Ident::new(&format!("{}Init", struct_name), struct_name.span());
+
+    if let syn::Data::Struct(ref data) = input.data {
+        if let syn::Fields::Named(ref fields) = data.fields {
+            // Generate fields for the init struct
+            let init_struct_fields = fields.named.iter().map(|f| {
+                let name = &f.ident;
+                let ty = &f.ty;
+                quote! { pub #name: #ty }
+            });
+
+            // Generate struct initialization code using the init struct
+            let struct_init_fields = fields.named.iter().map(|f| {
+                let name = &f.ident;
+                quote! { #name: init_struct.#name }
+            });
+
+            // Generate the new function and the init struct
+            let gen = quote! {
+                // Define a new struct to hold initialization parameters
+                pub struct #init_struct_name {
+                    #(#init_struct_fields),*
+                }
+
+                impl #struct_name {
+                    pub fn new(init_struct: #init_struct_name) -> Self {
+                        Self {
+                            #(#struct_init_fields,)*
+                            bolt_metadata: BoltMetadata::default(),
+                        }
+                    }
+                }
+            };
+            return gen;
+        }
+    }
+    quote! {}
+}

+ 0 - 2
crates/types/src/component_Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ.rs

@@ -1,7 +1,6 @@
 use bolt_lang::*;
 
 #[component_deserialize]
-#[derive(Clone, Copy)]
 pub struct ComponentFn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ {
     pub x: i64,
     pub y: i64,
@@ -11,7 +10,6 @@ pub struct ComponentFn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ {
 pub use ComponentFn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ as Position;
 
 #[component_deserialize]
-#[derive(Clone, Copy)]
 pub struct Entity {
     pub id: u64,
 }