Compare commits

...
10 Commits
Author SHA1 Message Date
selimaj-dev f6cf2be0ed Fixed a few things 2024-12-23 12:44:48 +01:00
selimaj-dev d28bd2fdef some fixes and changes 2024-12-23 12:26:32 +01:00
selimaj-dev 2d93b82802 some fixes 2024-12-23 12:06:47 +01:00
selimaj-dev be9b3cc0df some changes 2024-12-23 12:06:03 +01:00
selimaj-dev a5f018d0a8 some changes 2024-12-23 12:02:36 +01:00
selimaj-dev cee73fb885 some changes 2024-12-23 11:58:21 +01:00
selimaj-dev 2f1f2b3395 some changes 2024-12-23 01:37:37 +01:00
selimaj-dev 2d0668955e updated component 2024-12-23 00:28:14 +01:00
selimaj-dev 8550b5f6ff main 2024-12-22 23:54:47 +01:00
selimaj-dev 8bb0116c1d component macro 2024-12-22 23:54:33 +01:00
3 changed files with 74 additions and 23 deletions
+5 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "osui-element" name = "osui-element"
version = "0.1.14" version = "0.1.23"
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"
@@ -9,6 +9,10 @@ license = "Apache-2.0"
proc-macro = true proc-macro = true
path = "./lib.rs" path = "./lib.rs"
[[bin]]
path = "./main.rs"
name = "osui-element"
[dependencies] [dependencies]
proc-macro2 = "1.0.89" proc-macro2 = "1.0.89"
quote = "1.0" quote = "1.0"
+54 -22
View File
@@ -1,7 +1,8 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{ use syn::{
parse::Parser, parse_macro_input, DeriveInput, Fields, GenericParam, Lifetime, LifetimeParam, parse::Parser, parse_macro_input, DeriveInput, FnArg, GenericParam, ItemFn, Lifetime,
LifetimeParam, PatIdent, PatType,
}; };
#[proc_macro_attribute] #[proc_macro_attribute]
@@ -16,16 +17,15 @@ pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
if ast.generics.lifetimes().count() == 0 && !has_generics { if ast.generics.lifetimes().count() == 0 && !has_generics {
ast.generics ast.generics
.params .params
.push(GenericParam::Lifetime(LifetimeParam::new(Lifetime::new( .push(syn::GenericParam::Lifetime(LifetimeParam::new(
"'a", Lifetime::new("'a", proc_macro2::Span::call_site()),
proc_macro2::Span::call_site(), )));
))));
} }
// Modify the struct fields to include additional fields // Modify the struct fields to include additional fields
match &mut ast.data { match &mut ast.data {
syn::Data::Struct(ref mut struct_data) => { syn::Data::Struct(ref mut struct_data) => {
if let Fields::Named(fields) = &mut struct_data.fields { if let syn::Fields::Named(fields) = &mut struct_data.fields {
fields.named.push( fields.named.push(
syn::Field::parse_named syn::Field::parse_named
.parse2(quote! { pub children: Children }) .parse2(quote! { pub children: Children })
@@ -90,25 +90,57 @@ pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
} }
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn elem_fn(_args: TokenStream, input: TokenStream) -> TokenStream { pub fn component(_: TokenStream, input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput); let input_fn = parse_macro_input!(input as ItemFn);
let struct_name = &ast.ident;
let func_name = syn::Ident::new( let fn_name = input_fn.sig.ident.clone();
&struct_name.to_string().to_lowercase(), let code = input_fn.block;
proc_macro2::Span::call_site(), let visibility = input_fn.vis;
); let return_type = match input_fn.sig.output {
syn::ReturnType::Default => syn::parse_quote! { Element },
syn::ReturnType::Type(_, t) => t,
};
let elem_fn = quote! { let lifetimes: Vec<_> = input_fn
pub fn #func_name<'a>() -> Box<#struct_name<'a>> { .sig
Box::new(#struct_name::default()) .generics
.params
.iter()
.filter_map(|param| {
if let GenericParam::Lifetime(lifetime) = param {
Some(&lifetime.lifetime)
} else {
None
}
})
.collect();
let mut struct_fields = Vec::new();
for arg in input_fn.sig.inputs.iter() {
if let FnArg::Typed(PatType { pat, ty, .. }) = arg {
if let syn::Pat::Ident(PatIdent { ident, .. }) = &**pat {
let field_name = ident.clone();
let field_type = ty.clone();
struct_fields.push(quote! { pub #field_name: #field_type });
}
}
}
let expanded = quote! {
#[derive(Debug, Default)]
#[allow(non_camel_case_types)]
#visibility struct #fn_name<#(#lifetimes),*> {
#(#struct_fields),*
}
impl <#(#lifetimes),*> Component for #fn_name <#(#lifetimes),*> {
type Element = #return_type;
fn create_element(self) -> Self::Element {
#code
}
} }
}; };
let expanded = quote! { TokenStream::from(expanded)
#ast
#elem_fn
};
expanded.into()
} }
+15
View File
@@ -0,0 +1,15 @@
use osui_element::component;
pub type Element = i32;
pub trait Component: std::fmt::Debug {
type Element;
fn create_element(self) -> Self::Element;
}
#[component]
pub fn MyComponent<'a>(age: &'a str) {
0
}
fn main() {}