Skip to main content

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}