Skip to content

Commit dde0e6d

Browse files
committed
add helper attribute to customized generated buffer struct ident
Signed-off-by: Teo Koon Peng <[email protected]>
1 parent 957f17d commit dde0e6d

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

macros/src/buffer.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
use proc_macro2::TokenStream;
22
use quote::{format_ident, quote};
3-
use syn::{parse_quote, Field, Ident, ItemStruct, Type};
3+
use syn::{parse_quote, Ident, ItemStruct, Type};
44

55
use crate::Result;
66

77
pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream> {
88
let struct_ident = &input_struct.ident;
99
let (impl_generics, ty_generics, where_clause) = input_struct.generics.split_for_impl();
10-
let (field_ident, field_type, _) = get_fields_map(&input_struct.fields)?;
11-
let struct_buffer_ident = format_ident!("__bevy_impulse_{}_Buffers", struct_ident);
10+
let (field_ident, field_type) = get_fields_map(&input_struct.fields)?;
11+
let BufferStructConfig {
12+
struct_name: buffer_struct_ident,
13+
} = BufferStructConfig::from_data_struct(&input_struct);
14+
let buffer_struct_vis = &input_struct.vis;
1215

1316
let buffer_struct: ItemStruct = parse_quote! {
1417
#[derive(Clone)]
1518
#[allow(non_camel_case_types)]
16-
struct #struct_buffer_ident #impl_generics #where_clause {
19+
#buffer_struct_vis struct #buffer_struct_ident #impl_generics #where_clause {
1720
#(
18-
#field_ident: ::bevy_impulse::Buffer<#field_type>,
21+
#buffer_struct_vis #field_ident: ::bevy_impulse::Buffer<#field_type>,
1922
)*
2023
}
2124
};
@@ -25,7 +28,7 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
2528

2629
let gen = quote! {
2730
impl #impl_generics ::bevy_impulse::JoinedValue for #struct_ident #ty_generics #where_clause {
28-
type Buffers = #struct_buffer_ident #ty_generics;
31+
type Buffers = #buffer_struct_ident #ty_generics;
2932
}
3033

3134
#buffer_struct
@@ -36,8 +39,8 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
3639
#(
3740
#field_ident: impl ::bevy_impulse::Bufferable<BufferType = ::bevy_impulse::Buffer<#field_type>>,
3841
)*
39-
) -> #struct_buffer_ident #ty_generics {
40-
#struct_buffer_ident {
42+
) -> #buffer_struct_ident #ty_generics {
43+
#buffer_struct_ident {
4144
#(
4245
#field_ident: #field_ident.into_buffer(builder),
4346
)*
@@ -53,52 +56,50 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
5356
Ok(gen.into())
5457
}
5558

56-
struct FieldConfig {
57-
buffer_type: TokenStream,
59+
struct BufferStructConfig {
60+
struct_name: Ident,
5861
}
5962

60-
impl FieldConfig {
61-
fn from_field(field: &Field) -> Self {
62-
let ty = &field.ty;
63-
let mut buffer_type = quote! { ::bevy_impulse::Buffer<#ty> };
63+
impl BufferStructConfig {
64+
fn from_data_struct(data_struct: &ItemStruct) -> Self {
65+
let mut config = Self {
66+
struct_name: format_ident!("__bevy_impulse_{}_Buffers", data_struct.ident),
67+
};
6468

65-
let attr = field
69+
let attr = data_struct
6670
.attrs
6771
.iter()
68-
.find(|attr| attr.path().is_ident("bevy_impulse"));
72+
.find(|attr| attr.path().is_ident("buffers"));
6973

7074
if let Some(attr) = attr {
7175
attr.parse_nested_meta(|meta| {
72-
if meta.path.is_ident("buffer_type") {
73-
buffer_type = meta.value()?.parse()?;
76+
if meta.path.is_ident("struct_name") {
77+
config.struct_name = meta.value()?.parse()?;
7478
}
7579
Ok(())
7680
})
77-
// panic if attribute is malformed, this will result in a compile error
81+
// panic if attribute is malformed, this will result in a compile error which is intended.
7882
.unwrap();
7983
}
8084

81-
Self { buffer_type }
85+
config
8286
}
8387
}
8488

85-
fn get_fields_map(fields: &syn::Fields) -> Result<(Vec<&Ident>, Vec<&Type>, Vec<FieldConfig>)> {
89+
fn get_fields_map(fields: &syn::Fields) -> Result<(Vec<&Ident>, Vec<&Type>)> {
8690
match fields {
8791
syn::Fields::Named(data) => {
8892
let mut idents = Vec::new();
8993
let mut types = Vec::new();
90-
let mut configs = Vec::new();
9194
for field in &data.named {
9295
let ident = field
9396
.ident
9497
.as_ref()
9598
.ok_or("expected named fields".to_string())?;
96-
let config = FieldConfig::from_field(field);
9799
idents.push(ident);
98100
types.push(&field.ty);
99-
configs.push(config);
100101
}
101-
Ok((idents, types, configs))
102+
Ok((idents, types))
102103
}
103104
_ => return Err("expected named fields".to_string()),
104105
}
@@ -113,7 +114,7 @@ fn impl_buffer_map_layout(
113114
) -> Result<proc_macro2::TokenStream> {
114115
let struct_ident = &buffer_struct.ident;
115116
let (impl_generics, ty_generics, where_clause) = buffer_struct.generics.split_for_impl();
116-
let (field_ident, field_type, _) = get_fields_map(&item_struct.fields)?;
117+
let (field_ident, field_type) = get_fields_map(&item_struct.fields)?;
117118
let map_key: Vec<String> = field_ident.iter().map(|v| v.to_string()).collect();
118119

119120
Ok(quote! {
@@ -154,7 +155,7 @@ fn impl_joined(
154155
let struct_ident = &joined_struct.ident;
155156
let item_struct_ident = &item_struct.ident;
156157
let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();
157-
let (field_ident, _, _) = get_fields_map(&item_struct.fields)?;
158+
let (field_ident, _) = get_fields_map(&item_struct.fields)?;
158159

159160
Ok(quote! {
160161
impl #impl_generics ::bevy_impulse::Joined for #struct_ident #ty_generics #where_clause {

macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn delivery_label_macro(item: TokenStream) -> TokenStream {
6565
/// The result error is the compiler error message to be displayed.
6666
type Result<T> = std::result::Result<T, String>;
6767

68-
#[proc_macro_derive(JoinedValue, attributes(bevy_impulse))]
68+
#[proc_macro_derive(JoinedValue, attributes(buffers))]
6969
pub fn derive_joined_value(input: TokenStream) -> TokenStream {
7070
let input = parse_macro_input!(input as ItemStruct);
7171
match impl_joined_value(&input) {

src/buffer/buffer_map.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,14 @@ mod tests {
406406
assert_eq!(value.generic, "world");
407407
assert!(context.no_unhandled_errors());
408408
}
409+
410+
#[derive(Clone, JoinedValue)]
411+
#[buffers(struct_name = FooBuffers)]
412+
struct TestDeriveWithConfig {}
413+
414+
#[test]
415+
fn test_derive_with_config() {
416+
// a compile test to check that the name of the generated struct is correct
417+
fn _check_buffer_struct_name(_: FooBuffers) {}
418+
}
409419
}

0 commit comments

Comments
 (0)