updated a few things

This commit is contained in:
2024-11-17 17:01:48 +01:00
parent 74767cf961
commit aa9d68f16f
11 changed files with 325 additions and 277 deletions
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "osui-element"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
path = "./lib.rs"
[dependencies]
quote = "1.0"
syn = { version = "2.0", features = ["full"] }
proc-macro2 = "*"
+125
View File
@@ -0,0 +1,125 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse::Parser, parse_macro_input, DeriveInput, Fields, LifetimeParam};
#[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;
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<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(
syn::Field::parse_named
.parse2(quote! { pub children: Children })
.unwrap(),
);
fields.named.push(
syn::Field::parse_named
.parse2(quote! { pub id: &'a str })
.unwrap(),
);
fields.named.push(
syn::Field::parse_named
.parse2(quote! { pub class: &'a str })
.unwrap(),
);
}
}
_ => panic!("`element` can only be used with structs"),
}
let expanded_impl = quote! {
impl<'a> ElementComponent 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 Box<dyn Element>> {
if let Children::Children(children, _) = &mut self.children {
for elem in children {
if elem.get_data().2 == id {
return Some(elem);
}
}
}
None
}
fn get_child(&mut self) -> Option<&mut Box<dyn Element>> {
if let Children::Children(children, child) = &mut self.children {
children.get_mut(*child)
} else {
None
}
}
}
};
let expanded = quote! {
#ast
#expanded_impl
};
expanded.into()
}
#[proc_macro_attribute]
pub fn elem_fn(_args: TokenStream, input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let struct_name = &ast.ident;
let func_name = syn::Ident::new(
&struct_name.to_string().to_lowercase(),
proc_macro2::Span::call_site(),
);
let elem_fn = quote! {
pub fn #func_name<'a>() -> Box<#struct_name<'a>> {
Box::new(#struct_name::default())
}
};
let expanded = quote! {
#ast
#elem_fn
};
expanded.into()
}