summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock17
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs134
-rw-r--r--varihappy-macros/Cargo.toml4
-rw-r--r--varihappy-macros/src/lib.rs137
5 files changed, 230 insertions, 63 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ea68854..7aee7ef 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,16 +12,6 @@ dependencies = [
]
[[package]]
-name = "proc_macros"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c8ef2e003e8285b3fc12d313756ea15b6de201013f917530728358882dec07f"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -50,10 +40,15 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "varihappy"
version = "0.1.0"
+dependencies = [
+ "varihappy-macros",
+]
[[package]]
name = "varihappy-macros"
version = "0.1.0"
dependencies = [
- "proc_macros",
+ "proc-macro2",
+ "quote",
+ "syn",
]
diff --git a/Cargo.toml b/Cargo.toml
index 565a11b..2c34d0a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,3 +7,4 @@ edition = "2024"
members = ["varihappy-macros"]
[dependencies]
+varihappy-macros = { path = "varihappy-macros" }
diff --git a/src/lib.rs b/src/lib.rs
index 90bec23..7bd5342 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,8 @@
+use varihappy_macros::{
+ reverse_expr_type, reverse_tuple_type, tuple_expr_len_rest, tuple_expr_mut, tuple_expr_ref,
+ tuple_type_len, tuple_type_len_rest,
+};
+
pub trait Tuple {
type AsRef<'a>: Tuple
where
@@ -22,47 +27,6 @@ pub trait Tuple1: Tuple {
fn into_rest(self) -> Self::Rest;
}
-macro_rules! impl_tuple {
- (
- A, $($letter: ident),* => $($letter_reverse: ident),*;
- 0, $($number: tt),* => $($number_reverse: tt),*
- ) => {
- impl<A,$($letter),*> Tuple for (A,$($letter,)*) {
- type AsRef<'a> = (&'a A,$(&'a $letter,)*) where Self: 'a;
- type AsMut<'a> = (&'a mut A,$(&'a mut $letter,)*) where Self: 'a;
- type Reversed = ($($letter_reverse,)*);
-
- fn as_ref(&self) -> Self::AsRef<'_> {
- (&self.0,$(&self.$number,)*)
- }
-
- fn as_mut(&mut self) -> Self::AsMut<'_> {
- (&mut self.0,$(&mut self.$number,)*)
- }
-
- fn rev(self) -> Self::Reversed {
- ($(self.$number_reverse,)*)
- }
- }
-
- impl<A, $($letter),*> Tuple1 for (A, $($letter,)*) {
- type Item0 = A;
- type Rest = ($($letter,)*);
-
- fn into_0(self) -> Self::Item0 {
- self.0
- }
- fn split_into(self) -> (Self::Item0, Self::Rest) {
- (self.0, ($(self.$number,)*))
- }
-
- fn into_rest(self) -> Self::Rest {
- ($(self.$number,)*)
- }
- }
- };
-}
-
impl Tuple for () {
type AsRef<'a>
= ()
@@ -118,10 +82,69 @@ impl<A> Tuple1 for (A,) {
fn into_rest(self) -> Self::Rest {}
}
-impl_tuple!(A, B => B, A; 0, 1 => 1, 0);
-impl_tuple!(A, B, C => C, B, A; 0, 1, 2 => 2, 1, 0);
-impl_tuple!(A, B, C, D => D, C, B, A; 0, 1, 2, 3 => 3, 2, 1, 0);
-impl_tuple!(A, B, C, D, E => E, D, C, B, A; 0, 1, 2, 3, 4 => 4, 3, 2, 1, 0);
+macro_rules! impl_tuple {
+ ($length: expr; $($letter: ident),*) => {
+ impl<$($letter),*> Tuple for tuple_type_len!($length) {
+ type AsRef<'a> = ($(&'a $letter,)*) where Self: 'a;
+ type AsMut<'a> = ($(&'a mut $letter,)*) where Self: 'a;
+ type Reversed = reverse_tuple_type!($length);
+
+ fn as_ref(&self) -> Self::AsRef<'_> {
+ tuple_expr_ref!($length)
+ }
+
+ fn as_mut(&mut self) -> Self::AsMut<'_> {
+ tuple_expr_mut!($length)
+ }
+
+ fn rev(self) -> Self::Reversed {
+ reverse_expr_type!($length)
+ }
+ }
+
+ impl<$($letter),*> Tuple1 for tuple_type_len!($length) {
+ type Item0 = A;
+ type Rest = tuple_type_len_rest!($length);
+
+ fn into_0(self) -> Self::Item0 {
+ self.0
+ }
+ fn split_into(self) -> (Self::Item0, Self::Rest) {
+ (self.0, tuple_expr_len_rest!($length))
+ }
+
+ fn into_rest(self) -> Self::Rest {
+ tuple_expr_len_rest!($length)
+ }
+ }
+ };
+}
+
+impl_tuple!(2; A, B);
+impl_tuple!(3; A, B, C);
+impl_tuple!(4; A, B, C, D);
+impl_tuple!(5; A, B, C, D, E);
+impl_tuple!(6; A, B, C, D, E, F);
+impl_tuple!(7; A, B, C, D, E, F, G);
+impl_tuple!(8; A, B, C, D, E, F, G, H);
+impl_tuple!(9; A, B, C, D, E, F, G, H, I);
+impl_tuple!(10; A, B, C, D, E, F, G, H, I, J);
+impl_tuple!(11; A, B, C, D, E, F, G, H, I, J, K);
+impl_tuple!(12; A, B, C, D, E, F, G, H, I, J, K, L);
+impl_tuple!(13; A, B, C, D, E, F, G, H, I, J, K, L, M);
+impl_tuple!(14; A, B, C, D, E, F, G, H, I, J, K, L, M, N);
+impl_tuple!(15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
+impl_tuple!(16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
+impl_tuple!(17; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
+impl_tuple!(18; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
+impl_tuple!(19; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
+impl_tuple!(20; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
+impl_tuple!(21; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
+impl_tuple!(22; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V);
+impl_tuple!(23; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W);
+impl_tuple!(24; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X);
+impl_tuple!(25; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y);
+impl_tuple!(26; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
macro_rules! tuple_trait {
(trait $trait_name: ident for $trait_minus1: ident {
@@ -155,3 +178,24 @@ tuple_trait!(trait Tuple2 for Tuple1 { type Item1; fn into_1; });
tuple_trait!(trait Tuple3 for Tuple2 { type Item2; fn into_2; });
tuple_trait!(trait Tuple4 for Tuple3 { type Item3; fn into_3; });
tuple_trait!(trait Tuple5 for Tuple4 { type Item4; fn into_4; });
+tuple_trait!(trait Tuple6 for Tuple5 { type Item5; fn into_5; });
+tuple_trait!(trait Tuple7 for Tuple6 { type Item6; fn into_6; });
+tuple_trait!(trait Tuple8 for Tuple7 { type Item7; fn into_7; });
+tuple_trait!(trait Tuple9 for Tuple8 { type Item8; fn into_8; });
+tuple_trait!(trait Tuple10 for Tuple9 { type Item9; fn into_9; });
+tuple_trait!(trait Tuple11 for Tuple10 { type Item10; fn into_10; });
+tuple_trait!(trait Tuple12 for Tuple11 { type Item11; fn into_11; });
+tuple_trait!(trait Tuple13 for Tuple12 { type Item12; fn into_12; });
+tuple_trait!(trait Tuple14 for Tuple13 { type Item13; fn into_13; });
+tuple_trait!(trait Tuple15 for Tuple14 { type Item14; fn into_14; });
+tuple_trait!(trait Tuple16 for Tuple15 { type Item15; fn into_15; });
+tuple_trait!(trait Tuple17 for Tuple16 { type Item16; fn into_16; });
+tuple_trait!(trait Tuple18 for Tuple17 { type Item17; fn into_17; });
+tuple_trait!(trait Tuple19 for Tuple18 { type Item18; fn into_18; });
+tuple_trait!(trait Tuple20 for Tuple19 { type Item19; fn into_19; });
+tuple_trait!(trait Tuple21 for Tuple20 { type Item20; fn into_20; });
+tuple_trait!(trait Tuple22 for Tuple21 { type Item21; fn into_21; });
+tuple_trait!(trait Tuple23 for Tuple22 { type Item22; fn into_22; });
+tuple_trait!(trait Tuple24 for Tuple23 { type Item23; fn into_23; });
+tuple_trait!(trait Tuple25 for Tuple24 { type Item24; fn into_24; });
+tuple_trait!(trait Tuple26 for Tuple25 { type Item25; fn into_25; });
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()
}