Skip to content

Commit 4f45bfd

Browse files
committed
Use the new ExtraAttributes struct to store derive
1 parent 7c15022 commit 4f45bfd

File tree

5 files changed

+49
-56
lines changed

5 files changed

+49
-56
lines changed

soa-derive-internal/src/input.rs

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
use std::convert::TryInto;
22

3-
use proc_macro2::{Span, TokenStream};
3+
use proc_macro2::Span;
44
use quote::quote;
5-
use syn::{
6-
Data, DeriveInput, Field, Ident, Lit, Meta, MetaList, MetaNameValue, NestedMeta, Visibility,
7-
};
5+
6+
use syn::{Data, DeriveInput, Field, Ident, Lit, Path, Visibility};
7+
use syn::{Meta, MetaList, MetaNameValue, NestedMeta};
88

99
/// Representing the struct we are deriving
1010
pub struct Input {
1111
/// The input struct name
1212
pub name: Ident,
13-
/// The list of traits to derive passed to `soa_derive` attribute
14-
pub derives: Vec<Ident>,
1513
/// The list of fields in the struct
1614
pub fields: Vec<Field>,
1715
/// The struct overall visibility
1816
pub visibility: Visibility,
19-
/// Additional attributes requested with `#[soa_attr(...)]`
17+
/// Additional attributes requested with `#[soa_attr(...)]` or
18+
/// `#[soa_derive()]`
2019
pub attrs: ExtraAttributes,
2120
}
2221

2322
pub struct ExtraAttributes {
23+
// did the user explicitly asked us to derive clone?
24+
pub derive_clone: bool,
25+
2426
pub vec: Vec<Meta>,
2527
pub slice: Vec<Meta>,
2628
pub slice_mut: Vec<Meta>,
@@ -33,6 +35,7 @@ pub struct ExtraAttributes {
3335
impl ExtraAttributes {
3436
fn new() -> ExtraAttributes {
3537
ExtraAttributes {
38+
derive_clone: false,
3639
vec: Vec::new(),
3740
slice: Vec::new(),
3841
slice_mut: Vec::new(),
@@ -101,6 +104,41 @@ impl ExtraAttributes {
101104
_ => panic!("expected #[soa_attr(...)], got #[{}]", quote!(#meta)),
102105
}
103106
}
107+
108+
/// Add a single trait from `#[soa_derive]`
109+
fn add_derive(&mut self, trait_: &str) {
110+
static EXCEPTIONS: &[&str] = &["Clone", "Deserialize", "Serialize"];
111+
112+
let derive = create_derive_meta(trait_);
113+
if !EXCEPTIONS.contains(&trait_) {
114+
self.slice.push(derive.clone());
115+
self.slice_mut.push(derive.clone());
116+
self.ref_.push(derive.clone());
117+
self.ref_mut.push(derive.clone());
118+
self.ptr.push(derive.clone());
119+
self.ptr_mut.push(derive.clone());
120+
}
121+
122+
// always add this derive to the Vec struct
123+
self.vec.push(derive);
124+
125+
if trait_ == "Clone" {
126+
self.derive_clone = true;
127+
}
128+
}
129+
}
130+
131+
fn create_derive_meta(name: &str) -> Meta {
132+
let mut nested = syn::punctuated::Punctuated::new();
133+
nested.push(NestedMeta::Meta(Meta::Path(Path::from(
134+
Ident::new(name, Span::call_site())
135+
))));
136+
137+
Meta::List(MetaList {
138+
path: Path::from(Ident::new("derive", Span::call_site())),
139+
paren_token: syn::token::Paren {span: Span::call_site()},
140+
nested: nested
141+
})
104142
}
105143

106144
impl Input {
@@ -110,7 +148,6 @@ impl Input {
110148
_ => panic!("#[derive(StructOfArray)] only supports struct"),
111149
};
112150

113-
let mut derives: Vec<Ident> = vec![];
114151
let mut extra_attrs = ExtraAttributes::new();
115152

116153
for attr in input.attrs {
@@ -122,7 +159,7 @@ impl Input {
122159
..
123160
}) => {
124161
for value in string.value().split(',') {
125-
derives.push(Ident::new(value.trim(), Span::call_site()));
162+
extra_attrs.add_derive(value.trim());
126163
}
127164
}
128165
_ => panic!(
@@ -138,44 +175,12 @@ impl Input {
138175

139176
Input {
140177
name: input.ident,
141-
derives: derives,
142178
fields: fields,
143179
visibility: input.vis,
144180
attrs: extra_attrs,
145181
}
146182
}
147183

148-
pub fn derive(&self) -> TokenStream {
149-
if self.derives.is_empty() {
150-
TokenStream::new()
151-
} else {
152-
let derives = &self.derives;
153-
quote!(
154-
#[derive(
155-
#(#derives,)*
156-
)]
157-
)
158-
}
159-
}
160-
161-
pub fn derive_with_exceptions(&self) -> TokenStream {
162-
if self.derives.is_empty() {
163-
TokenStream::new()
164-
} else {
165-
let derives = &self.derives.iter()
166-
.cloned()
167-
.filter(|name| name != "Clone")
168-
.filter(|name| name != "Deserialize")
169-
.filter(|name| name != "Serialize")
170-
.collect::<Vec<_>>();
171-
quote!(
172-
#[derive(
173-
#(#derives,)*
174-
)]
175-
)
176-
}
177-
}
178-
179184
pub fn vec_name(&self) -> Ident {
180185
Ident::new(&format!("{}Vec", self.name), Span::call_site())
181186
}

soa-derive-internal/src/ptr.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::input::Input;
66
pub fn derive(input: &Input) -> TokenStream {
77
let name = &input.name;
88
let visibility = &input.visibility;
9-
let other_derive = &input.derive_with_exceptions();
109
let attrs = &input.attrs.ptr;
1110
let mut_attrs = &input.attrs.ptr_mut;
1211
let vec_name = &input.vec_name();
@@ -43,7 +42,6 @@ pub fn derive(input: &Input) -> TokenStream {
4342
/// An analog of a pointer to
4443
#[doc = #doc_url]
4544
/// with struct of array layout.
46-
#other_derive
4745
#(#[#attrs])*
4846
#[derive(Copy, Clone)]
4947
#visibility struct #ptr_name {
@@ -56,7 +54,6 @@ pub fn derive(input: &Input) -> TokenStream {
5654
/// An analog of a mutable pointer to
5755
#[doc = #doc_url]
5856
/// with struct of array layout.
59-
#other_derive
6057
#(#[#mut_attrs])*
6158
#[derive(Copy, Clone)]
6259
#visibility struct #ptr_mut_name {

soa-derive-internal/src/refs.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::input::Input;
66
pub fn derive(input: &Input) -> TokenStream {
77
let name = &input.name;
88
let visibility = &input.visibility;
9-
let other_derive = &input.derive_with_exceptions();
109
let attrs = &input.attrs.ref_;
1110
let mut_attrs = &input.attrs.ref_mut;
1211
let vec_name = &input.vec_name();
@@ -39,7 +38,6 @@ pub fn derive(input: &Input) -> TokenStream {
3938
/// A reference to a
4039
#[doc = #doc_url]
4140
/// with struct of array layout.
42-
#other_derive
4341
#(#[#attrs])*
4442
#[derive(Copy, Clone)]
4543
#visibility struct #ref_name<'a> {
@@ -52,7 +50,6 @@ pub fn derive(input: &Input) -> TokenStream {
5250
/// A mutable reference to a
5351
#[doc = #doc_url]
5452
/// with struct of array layout.
55-
#other_derive
5653
#(#[#mut_attrs])*
5754
#visibility struct #ref_mut_name<'a> {
5855
#(

soa-derive-internal/src/slice.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use quote::quote;
66
use crate::input::Input;
77

88
pub fn derive(input: &Input) -> TokenStream {
9-
let other_derive = &input.derive_with_exceptions();
109
let visibility = &input.visibility;
1110
let slice_name = &input.slice_name();
1211
let attrs = &input.attrs.slice;
@@ -48,7 +47,6 @@ pub fn derive(input: &Input) -> TokenStream {
4847
/// .
4948
#[allow(dead_code)]
5049
#[derive(Copy, Clone)]
51-
#other_derive
5250
#(#[#attrs])*
5351
#visibility struct #slice_name<'a> {
5452
#(
@@ -216,7 +214,7 @@ pub fn derive(input: &Input) -> TokenStream {
216214
}
217215
};
218216

219-
if input.derives.contains(&Ident::new("Clone", Span::call_site())) {
217+
if input.attrs.derive_clone {
220218
generated.append_all(quote!{
221219
#[allow(dead_code)]
222220
impl<'a> #slice_name<'a> {
@@ -236,7 +234,6 @@ pub fn derive(input: &Input) -> TokenStream {
236234
}
237235

238236
pub fn derive_mut(input: &Input) -> TokenStream {
239-
let other_derive = &input.derive_with_exceptions();
240237
let visibility = &input.visibility;
241238
let slice_name = &input.slice_name();
242239
let slice_mut_name = &input.slice_mut_name();
@@ -282,7 +279,6 @@ pub fn derive_mut(input: &Input) -> TokenStream {
282279
#[doc = #vec_doc_url]
283280
/// .
284281
#[allow(dead_code)]
285-
#other_derive
286282
#(#[#attrs])*
287283
#visibility struct #slice_mut_name<'a> {
288284
#(
@@ -528,7 +524,7 @@ pub fn derive_mut(input: &Input) -> TokenStream {
528524
}
529525
};
530526

531-
if input.derives.contains(&Ident::new("Clone", Span::call_site())) {
527+
if input.attrs.derive_clone {
532528
generated.append_all(quote!{
533529
#[allow(dead_code)]
534530
impl<'a> #slice_mut_name<'a> {

soa-derive-internal/src/vec.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::input::Input;
88
pub fn derive(input: &Input) -> TokenStream {
99
let name = &input.name;
1010
let vec_name_str = format!("Vec<{}>", name);
11-
let other_derive = &input.derive();
1211
let attrs = &input.attrs.vec;
1312
let visibility = &input.visibility;
1413
let vec_name = &input.vec_name();
@@ -42,7 +41,6 @@ pub fn derive(input: &Input) -> TokenStream {
4241
#[doc = #vec_name_str]
4342
/// ` with Struct of Array (SoA) layout
4443
#[allow(dead_code)]
45-
#other_derive
4644
#(#[#attrs])*
4745
#visibility struct #vec_name {
4846
#(
@@ -352,7 +350,7 @@ pub fn derive(input: &Input) -> TokenStream {
352350
}
353351
};
354352

355-
if input.derives.contains(&Ident::new("Clone", Span::call_site())) {
353+
if input.attrs.derive_clone {
356354
generated.append_all(quote!{
357355
#[allow(dead_code)]
358356
impl #vec_name {

0 commit comments

Comments
 (0)