palette/cast/as_arrays_traits.rs
1use super::{
2 from_array_slice, from_array_slice_mut, into_array_slice, into_array_slice_mut, ArrayCast,
3};
4
5/// Trait for casting a reference to a collection of colors into a reference to
6/// a collection of arrays without copying.
7///
8/// This trait is meant as a more convenient alternative to the free functions
9/// in [`cast`][crate::cast], to allow method chaining among other things.
10///
11/// ## Examples
12///
13/// ```
14/// use palette::{cast::AsArrays, Srgb};
15///
16/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
17/// let slice: &[_] = &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
18/// let vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
19///
20/// assert_eq!(array.as_arrays(), &[[64, 139, 10], [93, 18, 214]]);
21/// assert_eq!(slice.as_arrays(), &[[64, 139, 10], [93, 18, 214]]);
22/// assert_eq!(vec.as_arrays(), &[[64, 139, 10], [93, 18, 214]]);
23/// ```
24pub trait AsArrays<A: ?Sized> {
25 /// Cast this collection of colors into a collection of arrays.
26 fn as_arrays(&self) -> &A;
27}
28
29/// Trait for casting a mutable reference to a collection of colors into a
30/// mutable reference to a collection of arrays without copying.
31///
32/// This trait is meant as a more convenient alternative to the free functions
33/// in [`cast`][crate::cast], to allow method chaining among other things.
34///
35/// ## Examples
36///
37/// ```
38/// use palette::{cast::AsArraysMut, Srgb};
39///
40/// let mut array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
41/// let slice_mut: &mut [_] = &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
42/// let mut vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
43///
44/// assert_eq!(array.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]);
45/// assert_eq!(slice_mut.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]);
46/// assert_eq!(vec.as_arrays_mut(), &mut [[64, 139, 10], [93, 18, 214]]);
47/// ```
48pub trait AsArraysMut<A: ?Sized> {
49 /// Cast this collection of colors into a mutable collection of arrays.
50 fn as_arrays_mut(&mut self) -> &mut A;
51}
52
53macro_rules! impl_as_arrays {
54 ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
55 $(
56 impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsArrays<[[T; N]]> for $owning
57 where
58 C: ArrayCast<Array = [T; N]>,
59 {
60 #[inline]
61 fn as_arrays(&self) -> &[[T; N]] {
62 into_array_slice(self.as_ref())
63 }
64 }
65
66 impl<'a, T, C, const N: usize $(, $($ty_input)+)?> AsArraysMut<[[T; N]]> for $owning
67 where
68 C: ArrayCast<Array = [T; N]>,
69 {
70 #[inline]
71 fn as_arrays_mut(&mut self) -> &mut [[T; N]] {
72 into_array_slice_mut(self.as_mut())
73 }
74 }
75 )*
76 };
77}
78
79impl_as_arrays!([C], [C; M] where (const M: usize));
80
81#[cfg(feature = "alloc")]
82impl_as_arrays!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);
83
84/// Trait for casting a reference to collection of arrays into a reference to
85/// collection of colors without copying.
86///
87/// This trait is meant as a more convenient alternative to the free functions
88/// in [`cast`][crate::cast], to allow method chaining among other things.
89///
90/// ## Examples
91///
92/// ```
93/// use palette::{cast::ArraysAs, Srgb};
94///
95/// let array: [_; 2] = [[64, 139, 10], [93, 18, 214]];
96/// let slice: &[_] = &[[64, 139, 10], [93, 18, 214]];
97/// let vec: Vec<_> = vec![[64, 139, 10], [93, 18, 214]];
98///
99/// let colors: &[Srgb<u8>] = array.arrays_as();
100/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
101///
102/// let colors: &[Srgb<u8>] = slice.arrays_as();
103/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
104///
105/// let colors: &[Srgb<u8>] = vec.arrays_as();
106/// assert_eq!(colors, &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
107/// ```
108pub trait ArraysAs<C: ?Sized> {
109 /// Cast this collection of arrays into a collection of colors.
110 fn arrays_as(&self) -> &C;
111}
112
113/// Trait for casting a mutable reference to collection of arrays into a mutable
114/// reference to collection of colors without copying.
115///
116/// This trait is meant as a more convenient alternative to the free functions
117/// in [`cast`][crate::cast], to allow method chaining among other things.
118///
119/// ## Examples
120///
121/// ```
122/// use palette::{cast::ArraysAsMut, Srgb};
123///
124/// let mut array: [_; 2] = [[64, 139, 10], [93, 18, 214]];
125/// let slice_mut: &mut [_] = &mut [[64, 139, 10], [93, 18, 214]];
126/// let mut vec: Vec<_> = vec![[64, 139, 10], [93, 18, 214]];
127///
128/// let colors: &mut [Srgb<u8>] = array.arrays_as_mut();
129/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
130///
131/// let colors: &mut [Srgb<u8>] = slice_mut.arrays_as_mut();
132/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
133///
134/// let colors: &mut [Srgb<u8>] = vec.arrays_as_mut();
135/// assert_eq!(colors, &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
136/// ```
137pub trait ArraysAsMut<C: ?Sized> {
138 /// Cast this collection of arrays into a mutable collection of colors.
139 fn arrays_as_mut(&mut self) -> &mut C;
140}
141
142macro_rules! impl_arrays_as {
143 ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
144 $(
145 impl<'a, T, C, const N: usize $(, $($ty_input)+)?> ArraysAs<[C]> for $owning
146 where
147 C: ArrayCast<Array = [T; N]>,
148 {
149 #[inline]
150 fn arrays_as(&self) -> &[C] {
151 from_array_slice(self.as_ref())
152 }
153 }
154
155 impl<'a, T, C, const N: usize $(, $($ty_input)+)?> ArraysAsMut<[C]> for $owning
156 where
157 C: ArrayCast<Array = [T; N]>,
158 {
159 #[inline]
160 fn arrays_as_mut(&mut self) -> &mut [C] {
161 from_array_slice_mut(self.as_mut())
162 }
163 }
164 )*
165 };
166}
167
168impl_arrays_as!([[T; N]], [[T; N]; M] where (const M: usize));
169
170#[cfg(feature = "alloc")]
171impl_arrays_as!(alloc::boxed::Box<[[T; N]]>, alloc::vec::Vec<[T; N]>);
172
173#[cfg(test)]
174mod test {
175 use crate::Srgb;
176
177 use super::{ArraysAs, ArraysAsMut, AsArrays, AsArraysMut};
178
179 #[test]
180 fn as_arrays() {
181 let slice: &[Srgb<u8>] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
182 let slice_mut: &mut [Srgb<u8>] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
183 let mut slice_box: Box<[Srgb<u8>]> =
184 vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice();
185 let mut vec: Vec<Srgb<u8>> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
186 let mut array: [Srgb<u8>; 2] = [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
187
188 let _: &[[u8; 3]] = slice.as_arrays();
189 let _: &[[u8; 3]] = slice_box.as_arrays();
190 let _: &[[u8; 3]] = vec.as_arrays();
191 let _: &[[u8; 3]] = array.as_arrays();
192
193 let _: &mut [[u8; 3]] = slice_mut.as_arrays_mut();
194 let _: &mut [[u8; 3]] = slice_box.as_arrays_mut();
195 let _: &mut [[u8; 3]] = vec.as_arrays_mut();
196 let _: &mut [[u8; 3]] = array.as_arrays_mut();
197 }
198
199 #[test]
200 fn arrays_as() {
201 let slice: &[[u8; 3]] = &[[1, 2, 3], [4, 5, 6]];
202 let slice_mut: &mut [[u8; 3]] = &mut [[1, 2, 3], [4, 5, 6]];
203 let mut slice_box: Box<[[u8; 3]]> = vec![[1, 2, 3], [4, 5, 6]].into_boxed_slice();
204 let mut vec: Vec<[u8; 3]> = vec![[1, 2, 3], [4, 5, 6]];
205 let mut array: [[u8; 3]; 2] = [[1, 2, 3], [4, 5, 6]];
206
207 let _: &[Srgb<u8>] = slice.arrays_as();
208 let _: &[Srgb<u8>] = slice_box.arrays_as();
209 let _: &[Srgb<u8>] = vec.arrays_as();
210 let _: &[Srgb<u8>] = array.arrays_as();
211
212 let _: &mut [Srgb<u8>] = slice_mut.arrays_as_mut();
213 let _: &mut [Srgb<u8>] = slice_box.arrays_as_mut();
214 let _: &mut [Srgb<u8>] = vec.arrays_as_mut();
215 let _: &mut [Srgb<u8>] = array.arrays_as_mut();
216 }
217}