Skip to content

Commit bd5198a

Browse files
Implement Extend for Vec (#64)
* feat: implement Extend for Vec (fix #51) * feat(soa-derive-internal/src/iter.rs): derive Extend for #ref_name items * docs(soa-derive-internal/src/refs.rs): fix typo
1 parent c6ef5a6 commit bd5198a

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

soa-derive-internal/src/iter.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ pub fn derive(input: &Input) -> TokenStream {
2525
.map(|field| field.ident.clone().unwrap())
2626
.collect::<Vec<_>>();
2727

28+
let fields_types = &input.fields.iter()
29+
.map(|field| field.ty.clone())
30+
.collect::<Vec<_>>();
31+
2832
let iter_type = input.map_fields_nested_or(
2933
|_, field_type| quote! { <#field_type as soa_derive::SoAIter<'a>>::Iter },
3034
|_, field_type| quote! { slice::Iter<'a, #field_type> },
@@ -289,6 +293,24 @@ pub fn derive(input: &Input) -> TokenStream {
289293
self.as_mut_slice().into_iter()
290294
}
291295
}
296+
297+
impl Extend<#name> for #vec_name {
298+
fn extend<I: IntoIterator<Item = #name>>(&mut self, iter: I) {
299+
for item in iter {
300+
self.push(item)
301+
}
302+
}
303+
}
304+
305+
impl<'a> Extend<#ref_name<'a>> for #vec_name
306+
// only expose if all fields are Clone
307+
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
308+
where #( for<'b> #fields_types: Clone, )*
309+
{
310+
fn extend<I: IntoIterator<Item = #ref_name<'a>>>(&mut self, iter: I) {
311+
self.extend(iter.into_iter().map(|item| item.to_owned()))
312+
}
313+
}
292314
});
293315
}
294316

soa-derive-internal/src/refs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn derive(input: &Input) -> TokenStream {
132132
/// into an owned value. This is only available if all fields
133133
/// implement `Clone`.
134134
pub fn to_owned(&self) -> #name
135-
// only expose to_owned is all fields are Clone
135+
// only expose to_owned if all fields are Clone
136136
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
137137
where #( for<'b> #fields_types: Clone, )*
138138
{
@@ -148,7 +148,7 @@ pub fn derive(input: &Input) -> TokenStream {
148148
/// into an owned value. This is only available if all fields
149149
/// implement `Clone`.
150150
pub fn to_owned(&self) -> #name
151-
// only expose to_owned is all fields are Clone
151+
// only expose to_owned if all fields are Clone
152152
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
153153
where #( for<'b> #fields_types: Clone, )*
154154
{

tests/iter.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,19 @@ fn from_iter() {
6969

7070
assert_eq!(particles, particles_from_iter)
7171
}
72+
73+
#[test]
74+
fn extend() {
75+
let vec_with_particles = vec![
76+
Particle::new(String::from("Na"), 0.0),
77+
Particle::new(String::from("Cl"), 0.0),
78+
Particle::new(String::from("Zn"), 0.0),
79+
];
80+
81+
let particles_from_iter: ParticleVec = vec_with_particles.clone().into_iter().collect();
82+
83+
let mut particles = ParticleVec::new();
84+
particles.extend(vec_with_particles);
85+
86+
assert_eq!(particles, particles_from_iter)
87+
}

0 commit comments

Comments
 (0)