some refractoring
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "osui-element"
|
name = "osui-element"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "The element attribute for defining elements in OSUI"
|
description = "The element attribute for defining elements in OSUI"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|||||||
@@ -1,46 +1,27 @@
|
|||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
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]
|
#[proc_macro_attribute]
|
||||||
pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
|
pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
let mut ast = parse_macro_input!(input as DeriveInput);
|
let mut ast = parse_macro_input!(input as DeriveInput);
|
||||||
let struct_name = &ast.ident;
|
|
||||||
|
|
||||||
match &mut ast.data {
|
// Add a lifetime if none exists
|
||||||
syn::Data::Struct(ref mut struct_data) => {
|
|
||||||
if ast.generics.lifetimes().count() == 0 {
|
if ast.generics.lifetimes().count() == 0 {
|
||||||
ast.generics
|
ast.generics
|
||||||
.params
|
.params
|
||||||
.push(syn::GenericParam::Lifetime(LifetimeParam::new(
|
.push(GenericParam::Lifetime(LifetimeParam::new(Lifetime::new(
|
||||||
syn::Lifetime::new("'a", proc_macro2::Span::call_site()),
|
"'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 let Fields::Named(fields) = &mut struct_data.fields {
|
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<usize> })
|
|
||||||
.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<usize> })
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
fields.named.push(
|
|
||||||
syn::Field::parse_named
|
|
||||||
.parse2(quote! { pub height: Value<usize> })
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
fields.named.push(
|
fields.named.push(
|
||||||
syn::Field::parse_named
|
syn::Field::parse_named
|
||||||
.parse2(quote! { pub children: Children })
|
.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"),
|
_ => 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>, 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<StyleName, Style>) {
|
|
||||||
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! {
|
let expanded = quote! {
|
||||||
#ast
|
#ast
|
||||||
#expanded_impl
|
|
||||||
};
|
};
|
||||||
|
|
||||||
expanded.into()
|
expanded.into()
|
||||||
@@ -134,7 +64,7 @@ pub fn elem_fn(_args: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let elem_fn = quote! {
|
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())
|
Box::new(#struct_name::default())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user