diff options
Diffstat (limited to 'varihappy-macros/src/lib.rs')
| -rw-r--r-- | varihappy-macros/src/lib.rs | 137 |
1 files changed, 131 insertions, 6 deletions
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() } |
