component macro

This commit is contained in:
2024-12-22 23:54:33 +01:00
parent 1b369b8d9a
commit 8bb0116c1d
2 changed files with 50 additions and 2 deletions
+5 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "osui-element" name = "osui-element"
version = "0.1.14" version = "0.1.15"
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]]
name = "osui-element"
path = "./main.rs"
[dependencies] [dependencies]
proc-macro2 = "1.0.89" proc-macro2 = "1.0.89"
quote = "1.0" quote = "1.0"
+45 -1
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, Fields, GenericParam, ItemFn, Lifetime,
LifetimeParam,
}; };
#[proc_macro_attribute] #[proc_macro_attribute]
@@ -112,3 +113,46 @@ pub fn elem_fn(_args: TokenStream, input: TokenStream) -> TokenStream {
expanded.into() expanded.into()
} }
#[proc_macro_attribute]
pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {
let input_fn = parse_macro_input!(input as ItemFn);
let fn_name = input_fn.sig.ident.clone();
let code = input_fn.block;
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 struct_fields = input_fn.sig.inputs.iter().filter_map(|arg| {
if let syn::FnArg::Typed(pat_type) = arg {
if let syn::Pat::Ident(pat_ident) = *pat_type.pat.clone() {
let field_name = pat_ident.ident;
let field_type = pat_type.ty.clone();
Some(quote! { pub #field_name: #field_type })
} else {
None
}
} else {
None
}
});
let expanded = quote! {
#[derive(Debug)]
#[allow(non_camel_case_types)]
#visibility struct #fn_name {
#(#struct_fields),*
}
impl #fn_name {
pub fn create_element(&self) -> #return_type {
#code
}
}
};
TokenStream::from(expanded)
}