Skip to content

Commit

Permalink
Implement Extend for Vec (#64)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
schneiderfelipe authored May 22, 2024
1 parent c6ef5a6 commit bd5198a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
22 changes: 22 additions & 0 deletions soa-derive-internal/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ pub fn derive(input: &Input) -> TokenStream {
.map(|field| field.ident.clone().unwrap())
.collect::<Vec<_>>();

let fields_types = &input.fields.iter()
.map(|field| field.ty.clone())
.collect::<Vec<_>>();

let iter_type = input.map_fields_nested_or(
|_, field_type| quote! { <#field_type as soa_derive::SoAIter<'a>>::Iter },
|_, field_type| quote! { slice::Iter<'a, #field_type> },
Expand Down Expand Up @@ -289,6 +293,24 @@ pub fn derive(input: &Input) -> TokenStream {
self.as_mut_slice().into_iter()
}
}

impl Extend<#name> for #vec_name {
fn extend<I: IntoIterator<Item = #name>>(&mut self, iter: I) {
for item in iter {
self.push(item)
}
}
}

impl<'a> Extend<#ref_name<'a>> for #vec_name
// only expose if all fields are Clone
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
where #( for<'b> #fields_types: Clone, )*
{
fn extend<I: IntoIterator<Item = #ref_name<'a>>>(&mut self, iter: I) {
self.extend(iter.into_iter().map(|item| item.to_owned()))
}
}
});
}

Expand Down
4 changes: 2 additions & 2 deletions soa-derive-internal/src/refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub fn derive(input: &Input) -> TokenStream {
/// into an owned value. This is only available if all fields
/// implement `Clone`.
pub fn to_owned(&self) -> #name
// only expose to_owned is all fields are Clone
// only expose to_owned if all fields are Clone
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
where #( for<'b> #fields_types: Clone, )*
{
Expand All @@ -148,7 +148,7 @@ pub fn derive(input: &Input) -> TokenStream {
/// into an owned value. This is only available if all fields
/// implement `Clone`.
pub fn to_owned(&self) -> #name
// only expose to_owned is all fields are Clone
// only expose to_owned if all fields are Clone
// https://github.com/rust-lang/rust/issues/48214#issuecomment-1150463333
where #( for<'b> #fields_types: Clone, )*
{
Expand Down
16 changes: 16 additions & 0 deletions tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,19 @@ fn from_iter() {

assert_eq!(particles, particles_from_iter)
}

#[test]
fn extend() {
let vec_with_particles = vec![
Particle::new(String::from("Na"), 0.0),
Particle::new(String::from("Cl"), 0.0),
Particle::new(String::from("Zn"), 0.0),
];

let particles_from_iter: ParticleVec = vec_with_particles.clone().into_iter().collect();

let mut particles = ParticleVec::new();
particles.extend(vec_with_particles);

assert_eq!(particles, particles_from_iter)
}

0 comments on commit bd5198a

Please sign in to comment.