soa_rs/soa_clone.rs
1use crate::{AsSoaRef, Soars};
2
3/// Construct an owned value by cloning fields from an SoA reference.
4///
5/// This trait allows constructing an owned instance of a type by cloning
6/// all fields from an SoA element.
7pub trait SoaClone: Soars {
8 /// Constructs `Self` by cloning all fields from the SoA reference.
9 ///
10 /// # Example
11 ///
12 /// ```
13 /// # use soa_rs::{Soars, soa, SoaClone};
14 /// #[derive(Soars, SoaClone, Debug, PartialEq, Clone)]
15 /// #[soa_derive(Debug)]
16 /// struct Point {
17 /// x: i32,
18 /// y: i32,
19 /// }
20 ///
21 /// let soa = soa![Point { x: 1, y: 2 }, Point { x: 3, y: 4 }];
22 /// let point_ref = soa.idx(0);
23 /// let owned = Point::soa_clone(point_ref);
24 /// assert_eq!(owned, Point { x: 1, y: 2 });
25 /// ```
26 fn soa_clone(item: <Self as Soars>::Ref<'_>) -> Self;
27}
28
29/// Analogous to [`clone`] or [`to_owned`], but for SoA array elements.
30///
31/// The opposite of [`SoaClone`].
32///
33/// [`to_owned`]: crate::__alloc::borrow::ToOwned::to_owned
34/// [`clone`]: core::clone::Clone::clone
35pub trait SoaToOwned<T>: AsSoaRef {
36 /// Construct an owned value from an SoA element.
37 ///
38 /// # Example
39 ///
40 /// ```
41 /// # use soa_rs::{Soars, SoaClone, soa, SoaToOwned};
42 /// #[derive(Soars, SoaClone, Debug, PartialEq, Clone)]
43 /// #[soa_derive(Debug)]
44 /// struct Point(f32, f32);
45 ///
46 /// let soa = soa![Point(1.0, 2.0), Point(3.0, 4.0)];
47 /// let el = soa.idx(1);
48 /// let owned = el.soa_to_owned();
49 /// assert_eq!(owned, Point(3.0, 4.0));
50 /// ```
51 fn soa_to_owned(&self) -> T;
52}
53
54/// Reflexive auto-implementation. Whenever [`SoaClone`] is implemented, so to
55/// is this one going in the opposite direction. This is analogous to the
56/// relationship between [`From`] and [`Into`].
57impl<S, D> SoaToOwned<D> for S
58where
59 S: AsSoaRef<Item = D>,
60 D: SoaClone,
61{
62 fn soa_to_owned(&self) -> D {
63 D::soa_clone(self.as_soa_ref())
64 }
65}