diff --git a/Cargo.toml b/Cargo.toml index c85312c..be3b04b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "osui-element" -version = "0.1.8" +version = "0.1.9" edition = "2021" description = "The element attribute for defining elements in OSUI" license = "Apache-2.0" diff --git a/lib.rs b/lib.rs index 7a1e1d6..fc6ce96 100644 --- a/lib.rs +++ b/lib.rs @@ -1,46 +1,27 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{parse::Parser, parse_macro_input, DeriveInput, Fields, LifetimeParam}; +use syn::{ + parse::Parser, parse_macro_input, DeriveInput, Fields, GenericParam, Lifetime, LifetimeParam, +}; -/// Sets the required values and traits for a struct to be a element. -/// You will still need to implement ElementCore yourself #[proc_macro_attribute] pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream { let mut ast = parse_macro_input!(input as DeriveInput); - let struct_name = &ast.ident; + // Add a lifetime if none exists + if ast.generics.lifetimes().count() == 0 { + ast.generics + .params + .push(GenericParam::Lifetime(LifetimeParam::new(Lifetime::new( + "'a", + proc_macro2::Span::call_site(), + )))); + } + + // Modify the struct fields to include additional fields match &mut ast.data { syn::Data::Struct(ref mut struct_data) => { - if ast.generics.lifetimes().count() == 0 { - ast.generics - .params - .push(syn::GenericParam::Lifetime(LifetimeParam::new( - syn::Lifetime::new("'a", proc_macro2::Span::call_site()), - ))); - } - if let Fields::Named(fields) = &mut struct_data.fields { - // Example fields, modify according to your needs - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub x: Value }) - .unwrap(), - ); - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub y: usize }) - .unwrap(), - ); - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub width: Value }) - .unwrap(), - ); - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub height: Value }) - .unwrap(), - ); fields.named.push( syn::Field::parse_named .parse2(quote! { pub children: Children }) @@ -66,59 +47,8 @@ pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream { _ => panic!("`element` can only be used with structs"), } - let expanded_impl = quote! { - impl<'a> ElementCore for #struct_name<'a> { - fn get_data(&self) -> (Value, usize, String) { - (self.x, self.y, self.id.to_string()) - } - fn update_data(&mut self, width: usize, height: usize) { - self.width.try_set_value(width); - self.height.try_set_value(height); - if let Children::Children(children, _) = &mut self.children { - for child in children { - child.update_data(width, height); - } - } - } - fn get_element_by_id(&mut self, id: &str) -> Option<&mut Element> { - if let Children::Children(children, _) = &mut self.children { - for elem in children { - if elem.get_data().2 == id { - return Some(elem); - } else if let Some(e) = elem.get_element_by_id(id) { - return Some(e); - } - } - } - None - } - fn get_child(&mut self) -> Option<&mut Element> { - if let Children::Children(children, child) = &mut self.children { - children.get_mut(*child) - } else { - None - } - } - fn set_styling(&mut self, styling: &std::collections::HashMap) { - if let Some(style) = styling.get(&StyleName::Class(self.class.to_string())) { - self.style = style.clone(); - } else if let Some(style) = styling.get(&StyleName::Id(self.id.to_string())) { - self.style = style.clone(); - } else if let Some(style) = styling.get(&StyleName::Component(stringify!(#struct_name).to_string())) { - self.style = style.clone(); - } - if let Children::Children(children, _) = &mut self.children { - for child in children { - child.set_styling(styling); - } - } - } - } - }; - let expanded = quote! { #ast - #expanded_impl }; expanded.into() @@ -134,7 +64,7 @@ pub fn elem_fn(_args: TokenStream, input: TokenStream) -> TokenStream { ); let elem_fn = quote! { - pub fn #func_name<'a>() -> Box<#struct_name<'a>> { + pub fn #func_name<'a, T>() -> Box<#struct_name<'a, T>> { Box::new(#struct_name::default()) } };