state_validation_derive/lib.rs
1use darling::FromDeriveInput;
2use proc_macro::TokenStream;
3use proc_macro2::Span;
4use syn::{Expr, Ident, Type, parse_macro_input};
5
6#[derive(darling::FromDeriveInput)]
7#[darling(attributes(state_filter_input))]
8struct StateFilterInputData {
9 remainder_type: Option<Type>,
10 remainder: Option<Expr>,
11}
12
13#[proc_macro_derive(StateFilterInput, attributes(state_filter_input))]
14pub fn state_filter_input(input: TokenStream) -> TokenStream {
15 let ast = parse_macro_input!(input as syn::DeriveInput);
16 let name = &ast.ident;
17 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
18 let data = StateFilterInputData::from_derive_input(&ast).unwrap();
19 let remainder_code = if let Some(remainder_type) = data.remainder_type {
20 let remainder_expr = data.remainder.expect("expected `remainder` expression");
21 quote::quote! {
22 impl #impl_generics state_validation::StateFilterInputConversion<Self> for #name #ty_generics #where_clause {
23 type Remainder = #remainder_type;
24 fn split_take(self) -> (Self, Self::Remainder) {
25 (self, #remainder_expr)
26 }
27 }
28 }
29 } else {
30 quote::quote! {
31 impl #impl_generics state_validation::StateFilterInputConversion<Self> for #name #ty_generics #where_clause {
32 type Remainder = ();
33 fn split_take(self) -> (Self, Self::Remainder) {
34 (self, ())
35 }
36 }
37 }
38 };
39 let mut generics_1 = ast.generics.clone();
40 generics_1
41 .params
42 .push(syn::GenericParam::Type(syn::TypeParam {
43 attrs: Vec::new(),
44 ident: Ident::new("T", Span::call_site()),
45 colon_token: None,
46 bounds: syn::punctuated::Punctuated::new(),
47 eq_token: None,
48 default: None,
49 }));
50 let (_impl_generics_1, _ty_generics_1, _where_clause_1) = generics_1.split_for_impl();
51 let mut generics_2 = ast.generics.clone();
52 generics_2
53 .params
54 .push(syn::GenericParam::Type(syn::TypeParam {
55 attrs: Vec::new(),
56 ident: Ident::new("T0", Span::call_site()),
57 colon_token: None,
58 bounds: syn::punctuated::Punctuated::new(),
59 eq_token: None,
60 default: None,
61 }));
62 generics_2
63 .params
64 .push(syn::GenericParam::Type(syn::TypeParam {
65 attrs: Vec::new(),
66 ident: Ident::new("T1", Span::call_site()),
67 colon_token: None,
68 bounds: syn::punctuated::Punctuated::new(),
69 eq_token: None,
70 default: None,
71 }));
72 let (_impl_generics_2, _ty_generics_2, _where_clause_2) = generics_2.split_for_impl();
73 quote::quote! {
74 impl #impl_generics state_validation::StateFilterInput for #name #ty_generics #where_clause {}
75 #remainder_code
76 /*impl #impl_generics_1 card_game::validation::StateFilterInputConversion<#name #ty_generics> for (#name #ty_generics, T) #where_clause {
77 type Remainder = (T,);
78 fn combine(input: #name #ty_generics, remainder: Self::Remainder) -> Self {
79 (input, remainder.0)
80 }
81 fn split_take(self) -> (#name #ty_generics, Self::Remainder) {
82 (self.0, (self.1,))
83 }
84 }
85 impl #impl_generics_2 card_game::validation::StateFilterInputConversion<#name #ty_generics> for (#name #ty_generics, T0, T1) #where_clause {
86 type Remainder = (T0, T1);
87 fn combine(input: #name #ty_generics, remainder: Self::Remainder) -> Self {
88 (input, remainder.0, remainder.1)
89 }
90 fn split_take(self) -> (#name #ty_generics, Self::Remainder) {
91 (self.0, (self.1, self.2))
92 }
93 }
94 impl #impl_generics_2 card_game::validation::StateFilterInputConversion<(#name #ty_generics, T0)> for (#name #ty_generics, T0, T1) #where_clause {
95 type Remainder = (T1,);
96 fn combine(input: (#name #ty_generics, T0), remainder: Self::Remainder) -> Self {
97 (input.0, input.1, remainder.0)
98 }
99 fn split_take(self) -> ((#name #ty_generics, T0), Self::Remainder) {
100 ((self.0, self.1), (self.2,))
101 }
102 }*/
103 /*impl #impl_generics_1 card_game::validation::StateFilterInputConversion<T> for (#name #ty_generics, T) #where_clause {
104 type Remainder = (#name #ty_generics,);
105 fn combine(input: T, remainder: Self::Remainder) -> Self {
106 (remainder.0, input)
107 }
108 fn split_take(self) -> (T, Self::Remainder) {
109 (self.0, (self.1,))
110 }
111 }*/
112 /*impl #impl_generics_2 card_game::validation::StateFilterInputConversion<(#name #ty_generics, T0)> for (#name #ty_generics, T0, T1) #where_clause {
113 type Remainder = (T1,);
114 fn combine(input: (#name #ty_generics, T0), remainder: Self::Remainder) -> Self {
115 (input.0, input.1, remainder.0)
116 }
117 fn split_take(self) -> ((#name #ty_generics, T0), Self::Remainder) {
118 ((self.0, self.1), (self.2,))
119 }
120 }*/
121 /*impl #impl_generics_2 card_game::validation::StateFilterInputConversion<(T0, T1)> for (T0, #name #ty_generics, T1) #where_clause {
122 type Remainder = (#name #ty_generics,);
123 fn combine(input: (T0, T1), remainder: Self::Remainder) -> Self {
124 (input.0, remainder.0, input.1)
125 }
126 fn split_take(self) -> ((T0, T1), Self::Remainder) {
127 ((self.0, self.2), (self.1,))
128 }
129 }
130 impl #impl_generics_2 card_game::validation::StateFilterInputConversion<(T0, T1)> for (#name #ty_generics, T0, T1) #where_clause {
131 type Remainder = (#name #ty_generics,);
132 fn combine(input: (T0, T1), remainder: Self::Remainder) -> Self {
133 (remainder.0, input.0, input.1)
134 }
135 fn split_take(self) -> ((T0, T1), Self::Remainder) {
136 ((self.1, self.2), (self.0,))
137 }
138 }*/
139 }
140 .into()
141}