Skip to content

Commit

Permalink
Tuple structs in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jan 15, 2024
1 parent 9cc480d commit 0bc1d27
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 23 deletions.
50 changes: 46 additions & 4 deletions dunge_macros/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::ident,
crate::member,
proc_macro2::{Span, TokenStream},
syn::{spanned::Spanned, Data, DataStruct, DeriveInput, GenericParam, Ident, Lifetime},
};
Expand Down Expand Up @@ -66,18 +66,18 @@ pub(crate) fn derive(input: DeriveInput) -> TokenStream {
});

let group_visit_members = iter::zip(0.., &fields).map(|(index, field)| {
let ident = ident::make(index, field.ident.as_ref());
let ident = member::make(index, field.ident.clone());
quote::quote! { ::dunge::bind::VisitMember::visit_member(self.#ident, visitor) }
});

let group_fields = iter::zip(0.., &fields).map(|(index, field)| {
let ident = ident::make(index, field.ident.as_ref());
let ident = member::make(index, field.ident.clone());
let ty = &field.ty;
quote::quote! { #ident: <#ty as ::dunge::group::MemberProjection>::Field }
});

let group_member_projections = iter::zip(0.., &fields).map(|(index, field)| {
let ident = ident::make(index, field.ident.as_ref());
let ident = member::make(index, field.ident.clone());
let ty = &field.ty;
quote::quote! { #ident: <#ty as ::dunge::group::MemberProjection>::member_projection(id, #index, out.clone()) }
});
Expand Down Expand Up @@ -158,4 +158,46 @@ mod tests {

assert_eq!(actual.to_string(), expected.to_string());
}

#[test]
fn derive_tuple_group() {
let input = quote::quote! {
struct Map<'a>(BoundTexture<'a>, &'a Sampler);
};

let input = syn::parse2(input).expect("parse input");
let actual = derive(input);
let expected = quote::quote! {
impl<'a> ::dunge::Group for Map<'a> {
type Projection = MapProjection<'static>;
const DEF: ::dunge::sl::Define<::dunge::types::MemberType> = ::dunge::sl::Define::new(&[
<BoundTexture<'a> as ::dunge::group::MemberProjection>::TYPE,
<&'a Sampler as ::dunge::group::MemberProjection>::TYPE,
]);
}

impl ::dunge::bind::Visit for Map<'_> {
fn visit<'a>(&'a self, visitor: &mut ::dunge::bind::Visitor<'a>) {
::dunge::bind::VisitMember::visit_member(self.0, visitor);
::dunge::bind::VisitMember::visit_member(self.1, visitor);
}
}

struct MapProjection<'a> {
0: <BoundTexture<'a> as ::dunge::group::MemberProjection>::Field,
1: <&'a Sampler as ::dunge::group::MemberProjection>::Field,
}

impl<'a> ::dunge::group::Projection for MapProjection<'a> {
fn projection(id: ::core::primitive::u32, out: ::dunge::sl::GlobalOut) -> Self {
Self {
0: <BoundTexture<'a> as ::dunge::group::MemberProjection>::member_projection(id, 0u32, out.clone()),
1: <&'a Sampler as ::dunge::group::MemberProjection>::member_projection(id, 1u32, out.clone()),
}
}
}
};

assert_eq!(actual.to_string(), expected.to_string());
}
}
8 changes: 0 additions & 8 deletions dunge_macros/src/ident.rs

This file was deleted.

16 changes: 8 additions & 8 deletions dunge_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
mod group;
mod ident;
mod member;
mod vertex;

use proc_macro::TokenStream;

/// Derive implementation for the vector type.
#[proc_macro_derive(Vertex)]
pub fn derive_vertex(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input);
vertex::derive(input).into()
}

/// Derive implementation for the group type.
#[proc_macro_derive(Group)]
pub fn derive_group(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input);
group::derive(input).into()
}

/// Derive implementation for the vector type.
#[proc_macro_derive(Vertex)]
pub fn derive_vertex(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input);
vertex::derive(input).into()
}
14 changes: 14 additions & 0 deletions dunge_macros/src/member.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use {
proc_macro2::{Ident, Span},
syn::{Index, Member},
};

pub(crate) fn make(index: u32, ident: Option<Ident>) -> Member {
match ident {
Some(ident) => Member::Named(ident),
None => Member::Unnamed(Index {
index,
span: Span::call_site(),
}),
}
}
42 changes: 39 additions & 3 deletions dunge_macros/src/vertex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::ident,
crate::member,
proc_macro2::TokenStream,
syn::{meta::ParseNestedMeta, spanned::Spanned, Attribute, Data, DataStruct, DeriveInput},
};
Expand Down Expand Up @@ -39,13 +39,13 @@ pub(crate) fn derive(input: DeriveInput) -> TokenStream {
});

let projection_fields = iter::zip(0.., &fields).map(|(index, field)| {
let ident = ident::make(index, field.ident.as_ref());
let ident = member::make(index, field.ident.clone());
let ty = &field.ty;
quote::quote! { #ident: <#ty as ::dunge::vertex::InputProjection>::Field }
});

let projection_inputs = iter::zip(0.., &fields).map(|(index, field)| {
let ident = ident::make(index, field.ident.as_ref());
let ident = member::make(index, field.ident.clone());
let ty = &field.ty;
quote::quote! { #ident: <#ty as ::dunge::vertex::InputProjection>::input_projection(id, #index) }
});
Expand Down Expand Up @@ -126,4 +126,40 @@ mod tests {

assert_eq!(actual.to_string(), expected.to_string());
}

#[test]
fn derive_tuple_vertex() {
let input = quote::quote! {
#[repr(C)]
struct Vert([f32; 2], [f32; 3]);
};

let input = syn::parse2(input).expect("parse input");
let actual = derive(input);
let expected = quote::quote! {
unsafe impl ::dunge::Vertex for Vert {
type Projection = VertProjection;
const DEF: ::dunge::sl::Define<::dunge::types::VectorType> = ::dunge::sl::Define::new(&[
<[f32; 2] as ::dunge::vertex::InputProjection>::TYPE,
<[f32; 3] as ::dunge::vertex::InputProjection>::TYPE,
]);
}

struct VertProjection {
0: <[f32; 2] as ::dunge::vertex::InputProjection>::Field,
1: <[f32; 3] as ::dunge::vertex::InputProjection>::Field,
}

impl ::dunge::vertex::Projection for VertProjection {
fn projection(id: ::core::primitive::u32) -> Self {
Self {
0: <[f32; 2] as ::dunge::vertex::InputProjection>::input_projection(id, 0u32),
1: <[f32; 3] as ::dunge::vertex::InputProjection>::input_projection(id, 1u32),
}
}
}
};

assert_eq!(actual.to_string(), expected.to_string());
}
}

0 comments on commit 0bc1d27

Please sign in to comment.