diff options
| author | Mica White <botahamec@outlook.com> | 2026-05-11 22:49:50 -0400 |
|---|---|---|
| committer | Mica White <botahamec@outlook.com> | 2026-05-11 22:49:50 -0400 |
| commit | fd835b4ce895d83940cca0107fd03c7b035506ac (patch) | |
| tree | 2e0c0b1a9d3a6c6faeaf035ede20ada0ee5759e8 /varihappy-macros | |
| parent | 3b3428d67ec465ee860c9cafcb10b99a2a2d37ec (diff) | |
Use proc macros to expand the number of traits
Diffstat (limited to 'varihappy-macros')
| -rw-r--r-- | varihappy-macros/Cargo.toml | 4 | ||||
| -rw-r--r-- | varihappy-macros/src/lib.rs | 137 |
2 files changed, 134 insertions, 7 deletions
diff --git a/varihappy-macros/Cargo.toml b/varihappy-macros/Cargo.toml index 968ce85..3999ad5 100644 --- a/varihappy-macros/Cargo.toml +++ b/varihappy-macros/Cargo.toml @@ -7,4 +7,6 @@ edition = "2024" proc-macro = true [dependencies] -proc_macros = "0.1.0" +proc-macro2 = "1" +syn = "2" +quote = "1" diff --git a/varihappy-macros/src/lib.rs b/varihappy-macros/src/lib.rs index 561962c..522d333 100644 --- a/varihappy-macros/src/lib.rs +++ b/varihappy-macros/src/lib.rs @@ -1,15 +1,140 @@ -use proc_macro::{Ident, Span, TokenStream, TokenTree}; +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro2::{Ident, Literal, Span}; +use quote::quote; +use syn::{Field, LitInt}; #[proc_macro] pub fn concat_idents(input: TokenStream) -> TokenStream { let mut buffer = String::new(); for token in input { - if let TokenTree::Ident(identifier) = token { - buffer.push_str(&identifier.to_string()); - } + buffer.push_str(&token.to_string()); } - let mut stream = TokenStream::new(); + let mut stream = proc_macro2::TokenStream::new(); stream.extend([Ident::new(&buffer, Span::call_site())]); - stream + stream.into() +} + +#[proc_macro] +pub fn number_to_generic(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let identifier = Ident::new( + match number { + 0 => "A", + 1 => "B", + 2 => "C", + 3 => "D", + 4 => "E", + 5 => "F", + 6 => "G", + 7 => "H", + 8 => "I", + 9 => "J", + 10 => "K", + 11 => "L", + 12 => "M", + 13 => "N", + 14 => "O", + 15 => "P", + 16 => "Q", + 17 => "R", + 18 => "S", + 19 => "T", + 20 => "U", + 21 => "V", + 22 => "W", + 23 => "X", + 24 => "Y", + 25 => "Z", + _ => panic!("Expected a number less than 26"), + }, + Span::call_site(), + ); + + quote! { #identifier }.into() +} + +#[proc_macro] +pub fn tuple_type_len(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = 0..number; + quote! { (#(::varihappy_macros::number_to_generic!(#num),)*) }.into() +} + +#[proc_macro] +pub fn tuple_type_ref(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = 0..number; + quote! { (#(&'a ::varihappy_macros::number_to_generic!(#num),)*) }.into() +} + +#[proc_macro] +pub fn tuple_type_mut(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = 0..number; + quote! { (#(&'a mut ::varihappy_macros::number_to_generic!(#num),)*) }.into() +} + +#[proc_macro] +pub fn reverse_tuple_type(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = (0..number).rev(); + quote! { (#(::varihappy_macros::number_to_generic!(#num),)*) }.into() +} + +#[proc_macro] +pub fn tuple_type_len_rest(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = 1..number; + quote! { (#(::varihappy_macros::number_to_generic!(#num),)*) }.into() +} + +#[proc_macro] +pub fn tuple_expr_ref(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = (0..number).map(Literal::u128_unsuffixed); + quote! { (#(&self.#num,)*) }.into() +} + +#[proc_macro] +pub fn tuple_expr_mut(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = (0..number).map(Literal::u128_unsuffixed); + quote! { (#(&mut self.#num,)*) }.into() +} + +#[proc_macro] +pub fn reverse_expr_type(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = (0..number).rev().map(Literal::u128_unsuffixed); + quote! { (#(self.#num,)*) }.into() +} + +#[proc_macro] +pub fn tuple_expr_len_rest(input: TokenStream) -> TokenStream { + let number = syn::parse_macro_input!(input as LitInt); + let number: u128 = number.base10_parse().expect("a number 0..=u128::MAX"); + + let num = (1..number).map(Literal::u128_unsuffixed); + quote! { (#(self.#num,)*) }.into() } |
