i did some stuff, honestly it starts to build pretty well if i might sayy

This commit is contained in:
Rusty Striker 2024-09-28 20:13:11 +03:00
parent 22319e84a1
commit 9189d9cd88
Signed by: RustyStriker
GPG key ID: 87E4D691632DFF15
22 changed files with 689 additions and 176 deletions

View file

@ -2,7 +2,7 @@ use proc_macro2::{Delimiter, Group, Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{parse_macro_input, DeriveInput, Ident};
#[proc_macro_derive(CharacterSheet, attributes(Input, Field, FieldExpr, Seperator))]
#[proc_macro_derive(CharacterSheet, attributes(Input, InputExpr, Field, FieldExpr, Seperator))]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input as DeriveInput);
let mut output = quote! {
@ -44,7 +44,7 @@ fn get_type_ident_set(ty: &syn::Type) -> Option<Ident> {
Some(Ident::new("as_num", Span::call_site()))
} else if p.path.is_ident("bool") {
Some(Ident::new("as_bool", Span::call_site()))
} else { None }
} else { None }
}
_ => panic!("Invalid data type"),
}
@ -62,12 +62,26 @@ fn impl_inputs(data: &syn::Data) -> TokenStream {
let name = f.ident.clone().unwrap();
let attr = f.attrs.iter().find(|a| a.path.is_ident("Input"));
if let Some(attr) = attr {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
let arg: syn::LitStr = attr.parse_args().expect("No arguments supplied for Input attribute, usage: `Input(\"Name\")`");
items.extend(quote! {
(#arg.to_string(), EntryType::#t(self.#name.clone())),
})
let exp: Option<&syn::Attribute> = f.attrs.iter().find(|a| a.path.is_ident("InputExpr"));
if let Some(attr) = exp {
let exp: syn::Meta = attr.parse_meta().expect("Failed to parse MetaList!");
if let syn::Meta::List(l) = exp {
let from_input = &l.nested[1];
items.extend(quote! {
(#arg.to_string(), self.#from_input()),
})
}
else {
panic!("Failed parsing InputExpr attribute, expected `(&mut self, EntryType), (&self) -> EntryType`");
}
}
else {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
items.extend(quote! {
(#arg.to_string(), EntryType::#t(self.#name.clone())),
});
}
}
}
}
@ -92,12 +106,26 @@ fn impl_fields(data: &syn::Data) -> TokenStream {
let name = f.ident.clone().unwrap();
let input_attr = f.attrs.iter().find(|a| a.path.is_ident("Input"));
if let Some(attr) = input_attr {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
let arg: syn::LitStr = attr.parse_args().expect("No arguments supplied for Input attribute, usage: `Input(\"Name\")`");
items.extend(quote! {
(#arg.to_string(), EntryType::#t(self.#name.clone())),
})
let exp = f.attrs.iter().find(|a| a.path.is_ident("InputExpr"));
if let Some(attr) = exp {
let exp: syn::Meta = attr.parse_meta().expect("Failed to parse MetaList!");
if let syn::Meta::List(l) = exp {
let from_input = &l.nested[1];
items.extend(quote! {
(#arg.to_string(), self.#from_input()),
})
}
else {
panic!("Failed parsing InputExpr attribute, expected `(&mut self, EntryType), (&self) -> EntryType`");
}
}
else {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
items.extend(quote! {
(#arg.to_string(), EntryType::#t(self.#name.clone())),
});
}
}
let field_attr = f.attrs.iter().find(|a| a.path.is_ident("Field"));
if let Some(attr) = field_attr {
@ -140,11 +168,26 @@ fn impl_get(data: &syn::Data) -> TokenStream {
let name = f.ident.clone().unwrap();
let input_attr = f.attrs.iter().find(|a| a.path.is_ident("Input"));
if let Some(attr) = input_attr {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
let arg: syn::LitStr = attr.parse_args().expect("No arguments supplied for Input attribute, usage: `Input(\"Name\")`");
match_hands.extend(quote! {
#arg => Some(EntryType::#t(self.#name.clone())),
})
let exp: Option<&syn::Attribute> = f.attrs.iter().find(|a| a.path.is_ident("InputExpr"));
if let Some(attr) = exp {
let exp: syn::Meta = attr.parse_meta().expect("Failed to parse MetaList!");
if let syn::Meta::List(l) = exp {
let from_input = &l.nested[1];
match_hands.extend(quote! {
#arg => Some(self.#from_input()),
});
}
else {
panic!("Failed parsing InputExpr attribute, expected `(&mut self, EntryType), (&self) -> EntryType`");
}
}
else {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
match_hands.extend(quote! {
#arg => Some(EntryType::#t(self.#name.clone())),
});
}
}
let field_attr = f.attrs.iter().find(|a| a.path.is_ident("Field"));
if let Some(attr) = field_attr {
@ -188,11 +231,26 @@ fn impl_set(data: &syn::Data) -> TokenStream {
let name = f.ident.clone().unwrap();
let input_attr = f.attrs.iter().find(|a| a.path.is_ident("Input"));
if let Some(attr) = input_attr {
let t = get_type_ident_set(&f.ty).expect(&format!("Invalid type for input: {}", name));
let arg: syn::LitStr = attr.parse_args().expect("No arguments supplied for Input attribute, usage: `Input(\"Name\")`");
match_hands.extend(quote! {
#arg => self.#name = value.#t(),
})
let exp = f.attrs.iter().find(|a| a.path.is_ident("InputExpr"));
if let Some(attr) = exp {
let exp: syn::Meta = attr.parse_meta().expect("Failed to parse MetaList!");
if let syn::Meta::List(l) = exp {
let to_input = &l.nested[0];
match_hands.extend(quote! {
#arg => self.#to_input(value),
});
}
else {
panic!("Failed parsing InputExpr attribute, expected `(&mut self, EntryType), (&self) -> EntryType`");
}
}
else {
let t = get_type_ident_set(&f.ty).expect(&format!("Invalid type for input: {}", name));
match_hands.extend(quote! {
#arg => self.#name = value.#t(),
});
}
}
}
}
@ -221,12 +279,26 @@ fn impl_display(data: &syn::Data) -> TokenStream {
}
let input_attr = f.attrs.iter().find(|a| a.path.is_ident("Input"));
if let Some(attr) = input_attr {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
let arg: syn::LitStr = attr.parse_args().expect("No arguments supplied for Input attribute, usage: `Input(\"Name\")`");
items.extend(quote! {
Some((#arg.to_string(), EntryType::#t(self.#name.clone()))),
})
let exp = f.attrs.iter().find(|a| a.path.is_ident("InputExpr"));
if let Some(attr) = exp {
let exp: syn::Meta = attr.parse_meta().expect("Failed to parse MetaList!");
if let syn::Meta::List(l) = exp {
let from_input = &l.nested[1];
items.extend(quote! {
Some((#arg.to_string(), self.#from_input())),
})
}
else {
panic!("Failed parsing InputExpr attribute, expected `(&mut self, EntryType), (&self) -> EntryType`");
}
}
else {
let t = get_type_ident(&f.ty).expect(&format!("Invalid type for input: {}", name));
items.extend(quote! {
Some((#arg.to_string(), EntryType::#t(self.#name.clone()))),
});
}
}
let field_attr = f.attrs.iter().find(|a| a.path.is_ident("Field"));
if let Some(attr) = field_attr {