use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::{ToTokens, format_ident, quote}; use syn::Ident; struct Query { components: Vec, filter: Ident, } impl Query { pub fn new(components: impl Iterator, filter_id: usize) -> Self { Self { components: components.collect(), filter: format_ident!("Filter{filter_id}"), } } pub fn types(&self) -> proc_macro2::TokenStream { let component_list = self .components .iter() .map(|c| quote! { #c, }) .collect::>(); let components = if component_list.len() == 1 { let component = &component_list[0]; quote! { #component } } else { quote! { ( #(#component_list)* ) } }; components } pub fn filter(&self) -> &Ident { &self.filter } } impl ToTokens for Query { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { let component_list = self .components .iter() .map(|c| quote! { &mut #c, }) .collect::>(); let components = if component_list.len() == 1 { let component = &component_list[0]; quote! { #component } } else { quote! { ( #(#component_list)* ) } }; let filter = self.filter.clone(); proc_macro2::TokenStream::from(quote! { Query<#components, #filter> }) .to_tokens(tokens); } } struct Update { queries: Vec, resources: Vec, } impl Update { pub fn new(queries: impl Iterator, resources: usize) -> Self { Self { queries: queries .enumerate() .map(|(query, component_count)| { Query::new( (1..component_count).map(|component| format_ident!("C{component}Q{query}")), query, ) }) .collect(), resources: (0..resources) .map(|resource| format_ident!("Res{resource}")) .collect(), } } pub fn query_types(&self) } pub fn update(max_components: usize, max_queries: usize) -> TokenStream { TokenStream::from(quote! { impl }) }