rstsr_common/
pack_array.rs1use crate::prelude_dev::*;
4use std::mem::ManuallyDrop;
5
6pub trait PackableArrayAPI<T, const N: usize> {
7 type Array;
8 type ArrayVec;
9}
10
11pub trait PackArrayAPI<T> {
12 fn pack_array_f<const N: usize>(self) -> Result<Self::ArrayVec>
13 where
14 Self: PackableArrayAPI<T, N>;
15 fn pack_array<const N: usize>(self) -> Self::ArrayVec
16 where
17 Self: PackableArrayAPI<T, N> + Sized,
18 {
19 self.pack_array_f().unwrap()
20 }
21}
22
23pub trait UnpackArrayAPI {
24 type Output;
25 fn unpack_array(self) -> Self::Output;
26}
27
28impl<T, const N: usize> PackableArrayAPI<T, N> for Vec<T> {
31 type Array = [T; N];
32 type ArrayVec = Vec<[T; N]>;
33}
34
35impl<T> PackArrayAPI<T> for Vec<T> {
36 fn pack_array_f<const N: usize>(self) -> Result<<Self as PackableArrayAPI<T, N>>::ArrayVec> {
37 let len = self.len();
38 rstsr_assert!(
39 len % N == 0,
40 InvalidValue,
41 "Length of Vec<T> {len} must be a multiple to cast into Vec<[T; {N}]>"
42 )?;
43 let vec = ManuallyDrop::new(self);
44 let arr = unsafe { Vec::from_raw_parts(vec.as_ptr() as *mut [T; N], len / N, len / N) };
45 Ok(arr)
46 }
47}
48
49impl<T, const N: usize> UnpackArrayAPI for Vec<[T; N]> {
50 type Output = Vec<T>;
51
52 fn unpack_array(self) -> Self::Output {
53 let len = self.len();
54 let arr = ManuallyDrop::new(self);
55 unsafe { Vec::from_raw_parts(arr.as_ptr() as *mut T, len * N, len * N) }
56 }
57}
58
59impl<'l, T, const N: usize> PackableArrayAPI<T, N> for &'l [T] {
64 type Array = [T; N];
65 type ArrayVec = &'l [[T; N]];
66}
67
68impl<T> PackArrayAPI<T> for &[T] {
69 fn pack_array_f<const N: usize>(self) -> Result<<Self as PackableArrayAPI<T, N>>::ArrayVec> {
70 let len = self.len();
71 rstsr_assert!(
72 len % N == 0,
73 InvalidValue,
74 "Length of &[T] {len} must be a multiple to cast into Vec<[T; {N}]>"
75 )?;
76 let arr = unsafe { core::slice::from_raw_parts(self.as_ptr() as *const [T; N], len / N) };
77 Ok(arr)
78 }
79}
80
81impl<'l, T, const N: usize> UnpackArrayAPI for &'l [[T; N]] {
82 type Output = &'l [T];
83
84 fn unpack_array(self) -> Self::Output {
85 let len = self.len();
86 unsafe { core::slice::from_raw_parts(self.as_ptr() as *const T, len * N) }
87 }
88}
89
90impl<'l, T, const N: usize> PackableArrayAPI<T, N> for &'l mut [T] {
95 type Array = [T; N];
96 type ArrayVec = &'l mut [[T; N]];
97}
98
99impl<T> PackArrayAPI<T> for &mut [T] {
100 fn pack_array_f<const N: usize>(self) -> Result<<Self as PackableArrayAPI<T, N>>::ArrayVec> {
101 let len = self.len();
102 rstsr_assert!(
103 len % N == 0,
104 InvalidValue,
105 "Length of &[T] {len} must be a multiple to cast into Vec<[T; {N}]>"
106 )?;
107 let arr = unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr() as *mut [T; N], len / N) };
108 Ok(arr)
109 }
110}
111
112impl<'l, T, const N: usize> UnpackArrayAPI for &'l mut [[T; N]] {
113 type Output = &'l mut [T];
114
115 fn unpack_array(self) -> Self::Output {
116 let len = self.len();
117 unsafe { core::slice::from_raw_parts_mut(self.as_ptr() as *mut T, len * N) }
118 }
119}
120
121#[cfg(test)]
124mod test {
125 use super::*;
126
127 #[test]
128 fn playground() {
129 let v1 = vec![1, 2, 3, 4, 5, 6];
130 let ptr_v1 = v1.as_ptr();
131
132 let a1: Vec<[i32; 2]> = v1.pack_array();
133 let ptr_a1 = a1.as_ptr();
134 assert_eq!(a1, vec![[1, 2], [3, 4], [5, 6]]);
135 assert_eq!(ptr_v1, ptr_a1 as *const i32);
136
137 let v2: Vec<i32> = a1.unpack_array();
138 let ptr_v2 = v2.as_ptr();
139 assert_eq!(v2, vec![1, 2, 3, 4, 5, 6]);
140 assert_eq!(ptr_v1, ptr_v2);
141 }
142}