Compare commits
10
Commits
1b369b8d9a
...
f6cf2be0ed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6cf2be0ed | ||
|
|
d28bd2fdef | ||
|
|
2d93b82802 | ||
|
|
be9b3cc0df | ||
|
|
a5f018d0a8 | ||
|
|
cee73fb885 | ||
|
|
2f1f2b3395 | ||
|
|
2d0668955e | ||
|
|
8550b5f6ff | ||
|
|
8bb0116c1d |
+5
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "osui-element"
|
||||
version = "0.1.14"
|
||||
version = "0.1.23"
|
||||
edition = "2021"
|
||||
description = "The element attribute for defining elements in OSUI"
|
||||
license = "Apache-2.0"
|
||||
@@ -9,6 +9,10 @@ license = "Apache-2.0"
|
||||
proc-macro = true
|
||||
path = "./lib.rs"
|
||||
|
||||
[[bin]]
|
||||
path = "./main.rs"
|
||||
name = "osui-element"
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.89"
|
||||
quote = "1.0"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
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]
|
||||
@@ -16,16 +17,15 @@ pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
if ast.generics.lifetimes().count() == 0 && !has_generics {
|
||||
ast.generics
|
||||
.params
|
||||
.push(GenericParam::Lifetime(LifetimeParam::new(Lifetime::new(
|
||||
"'a",
|
||||
proc_macro2::Span::call_site(),
|
||||
))));
|
||||
.push(syn::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 let Fields::Named(fields) = &mut struct_data.fields {
|
||||
if let syn::Fields::Named(fields) = &mut struct_data.fields {
|
||||
fields.named.push(
|
||||
syn::Field::parse_named
|
||||
.parse2(quote! { pub children: Children })
|
||||
@@ -90,25 +90,57 @@ pub fn element(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
#[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;
|
||||
pub fn component(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let input_fn = parse_macro_input!(input as ItemFn);
|
||||
|
||||
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 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 lifetimes: Vec<_> = input_fn
|
||||
.sig
|
||||
.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! {
|
||||
#ast
|
||||
#elem_fn
|
||||
#[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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user