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}