✨🧪♻️➕ vanth, vanth_derive: Add derive macro for Vanth
trait implementation
- Added `vanth_derive` crate with a procedural macro to automatically implement the `Vanth` trait for structs, including generics. - Refactored `vanth` crate by removing obsolete `vanth.rs` file. - Implemented `PartialEq` for `Ty` to enable comparisons with string values and another `Ty`. - Added integration tests for deriving `Vanth` with generic parameters. - Updated dependencies: added `quote`, `syn`, and `proc-macro2` crates.
This commit is contained in:
parent
94105daca1
commit
b36f178999
9 changed files with 119 additions and 23 deletions
12
crates/vanth_derive/Cargo.toml
Normal file
12
crates/vanth_derive/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "vanth_derive"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
proc-macro2.workspace = true
|
51
crates/vanth_derive/src/lib.rs
Normal file
51
crates/vanth_derive/src/lib.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput, GenericParam, Generics};
|
||||
use syn::parse_quote;
|
||||
|
||||
#[proc_macro_derive(Vanth)]
|
||||
pub fn vanth_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
let name = input.ident.clone();
|
||||
|
||||
let mut generics = input.generics.clone();
|
||||
|
||||
let type_params: Vec<syn::Ident> = generics.params.iter().filter_map(|param| {
|
||||
if let GenericParam::Type(type_param) = param {
|
||||
Some(type_param.ident.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let mut where_clause = generics.where_clause.clone().unwrap_or_else(|| parse_quote!(where ));
|
||||
for tp in &type_params {
|
||||
where_clause.predicates.push(parse_quote!(#tp : vanth::Vanth));
|
||||
}
|
||||
|
||||
let (impl_generics, ty_generics, _) = generics.split_for_impl();
|
||||
|
||||
let generics_code = if type_params.is_empty() {
|
||||
quote! { String::new() }
|
||||
} else {
|
||||
quote! {
|
||||
format!("<{}>", [#(#type_params::ty().path.join("::")),*].join(","))
|
||||
}
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics vanth::Vanth for #name #ty_generics #where_clause {
|
||||
fn ty() -> vanth::Ty {
|
||||
let module_path = module_path!();
|
||||
let mut path: Vec<String> = module_path.split("::").map(|s| s.to_string()).collect();
|
||||
let base_name = stringify!(#name);
|
||||
let generics_str = #generics_code;
|
||||
path.push(format!("{}{}", base_name, generics_str));
|
||||
vanth::Ty { path }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue