Start implementing proc macro solution for updates
This commit is contained in:
parent
fe1decdbbd
commit
4370853e23
2 changed files with 125 additions and 0 deletions
|
@ -1,8 +1,10 @@
|
||||||
mod pair_update;
|
mod pair_update;
|
||||||
mod single_update;
|
mod single_update;
|
||||||
|
mod update;
|
||||||
|
|
||||||
use pair_update::pair_update;
|
use pair_update::pair_update;
|
||||||
use single_update::single_update;
|
use single_update::single_update;
|
||||||
|
use update::update;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
@ -13,6 +15,31 @@ use syn::{
|
||||||
token::Comma,
|
token::Comma,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UpdateInfo {
|
||||||
|
max_components: usize,
|
||||||
|
max_queries: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for UpdateInfo {
|
||||||
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
|
let max_components = input.parse::<LitInt>()?.base10_parse()?;
|
||||||
|
input.parse::<Comma>()?;
|
||||||
|
let max_queries = input.parse::<LitInt>()?.base10_parse()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
max_components,
|
||||||
|
max_queries,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn implement_updates(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as UpdateInfo);
|
||||||
|
|
||||||
|
update(input.max_components, input.max_queries)
|
||||||
|
}
|
||||||
|
|
||||||
struct InputInfo {
|
struct InputInfo {
|
||||||
macro_ident: Ident,
|
macro_ident: Ident,
|
||||||
start: usize,
|
start: usize,
|
||||||
|
|
98
update_macros/src/update.rs
Normal file
98
update_macros/src/update.rs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
|
use quote::{ToTokens, format_ident, quote};
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
struct Query {
|
||||||
|
components: Vec<Ident>,
|
||||||
|
filter: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Query {
|
||||||
|
pub fn new(components: impl Iterator<Item = Ident>, 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::<Vec<_>>();
|
||||||
|
|
||||||
|
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::<Vec<_>>();
|
||||||
|
|
||||||
|
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<Query>,
|
||||||
|
resources: Vec<Ident>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Update {
|
||||||
|
pub fn new(queries: impl Iterator<Item = usize>, 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<Func, Filter, >
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue