palette/cast/as_uints_traits.rs
1use super::{from_uint_slice, from_uint_slice_mut, into_uint_slice, into_uint_slice_mut, UintCast};
2
3/// Trait for casting a reference to a collection of colors into a reference to
4/// a collection of unsigned integers without copying.
5///
6/// This trait is meant as a more convenient alternative to the free functions
7/// in [`cast`][crate::cast], to allow method chaining among other things.
8///
9/// ## Examples
10///
11/// ```
12/// use palette::{cast::AsUints, rgb::PackedArgb, Srgba};
13///
14/// let array: [PackedArgb; 2] = [
15/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
16/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
17/// ];
18/// let slice: &[PackedArgb] = &[
19/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
20/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
21/// ];
22/// let vec: Vec<PackedArgb> = vec![
23/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
24/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
25/// ];
26///
27/// assert_eq!(array.as_uints(), &[0xFF17C64C, 0xFF5D12D6]);
28/// assert_eq!(slice.as_uints(), &[0xFF17C64C, 0xFF5D12D6]);
29/// assert_eq!(vec.as_uints(), &[0xFF17C64C, 0xFF5D12D6]);
30/// ```
31pub trait AsUints<A: ?Sized> {
32 /// Cast this collection of colors into a collection of unsigned integers.
33 fn as_uints(&self) -> &A;
34}
35
36/// Trait for casting a mutable reference to a collection of colors into a
37/// mutable reference to a collection of unsigned integers without copying.
38///
39/// This trait is meant as a more convenient alternative to the free functions
40/// in [`cast`][crate::cast], to allow method chaining among other things.
41///
42/// ## Examples
43///
44/// ```
45/// use palette::{cast::AsUintsMut, rgb::PackedArgb, Srgba};
46///
47/// let mut array: [PackedArgb; 2] = [
48/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
49/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
50/// ];
51/// let slice_mut: &mut [PackedArgb] = &mut [
52/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
53/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
54/// ];
55/// let mut vec: Vec<PackedArgb> = vec![
56/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
57/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
58/// ];
59///
60/// assert_eq!(array.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]);
61/// assert_eq!(slice_mut.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]);
62/// assert_eq!(vec.as_uints_mut(), &mut [0xFF17C64C, 0xFF5D12D6]);
63/// ```
64pub trait AsUintsMut<A: ?Sized> {
65 /// Cast this collection of colors into a mutable collection of unsigned integers.
66 fn as_uints_mut(&mut self) -> &mut A;
67}
68
69macro_rules! impl_as_uints {
70 ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
71 $(
72 impl<'a, C $(, $($ty_input)+)?> AsUints<[C::Uint]> for $owning
73 where
74 C: UintCast,
75 {
76 #[inline]
77 fn as_uints(&self) -> &[C::Uint] {
78 into_uint_slice(self.as_ref())
79 }
80 }
81
82 impl<'a, C $(, $($ty_input)+)?> AsUintsMut<[C::Uint]> for $owning
83 where
84 C: UintCast,
85 {
86 #[inline]
87 fn as_uints_mut(&mut self) -> &mut [C::Uint] {
88 into_uint_slice_mut(self.as_mut())
89 }
90 }
91 )*
92 };
93}
94
95impl_as_uints!([C], [C; N] where (const N: usize));
96
97#[cfg(feature = "alloc")]
98impl_as_uints!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);
99
100/// Trait for casting a reference to a collection of unsigned integers into a
101/// reference to a collection of colors without copying.
102///
103/// This trait is meant as a more convenient alternative to the free functions
104/// in [`cast`][crate::cast], to allow method chaining among other things.
105///
106/// ## Examples
107///
108/// ```
109/// use palette::{cast::UintsAs, rgb::PackedArgb, Srgba};
110///
111/// let array: [_; 2] = [0xFF17C64C, 0xFF5D12D6];
112/// let slice: &[_] = &[0xFF17C64C, 0xFF5D12D6];
113/// let vec: Vec<_> = vec![0xFF17C64C, 0xFF5D12D6];
114///
115/// let colors: &[PackedArgb] = array.uints_as();
116/// assert_eq!(
117/// colors,
118/// &[
119/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
120/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
121/// ]
122/// );
123///
124/// let colors: &[PackedArgb] = slice.uints_as();
125/// assert_eq!(
126/// colors,
127/// &[
128/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
129/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
130/// ]
131/// );
132///
133/// let colors: &[PackedArgb] = vec.uints_as();
134/// assert_eq!(
135/// colors,
136/// &[
137/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
138/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
139/// ]
140/// );
141/// ```
142pub trait UintsAs<C: ?Sized> {
143 /// Cast this collection of unsigned integers into a collection of colors.
144 fn uints_as(&self) -> &C;
145}
146
147/// Trait for casting a mutable reference to a collection of unsigned integers
148/// into a mutable reference to a collection of colors without copying.
149///
150/// This trait is meant as a more convenient alternative to the free functions
151/// in [`cast`][crate::cast], to allow method chaining among other things.
152///
153/// ## Examples
154///
155/// ```
156/// use palette::{cast::UintsAsMut, rgb::PackedArgb, Srgba};
157///
158/// let mut array: [_; 2] = [0xFF17C64C, 0xFF5D12D6];
159/// let slice_mut: &mut [_] = &mut [0xFF17C64C, 0xFF5D12D6];
160/// let mut vec: Vec<_> = vec![0xFF17C64C, 0xFF5D12D6];
161///
162/// let colors: &mut [PackedArgb] = array.uints_as_mut();
163/// assert_eq!(
164/// colors,
165/// &mut [
166/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
167/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
168/// ]
169/// );
170///
171/// let colors: &mut [PackedArgb] = slice_mut.uints_as_mut();
172/// assert_eq!(
173/// colors,
174/// &mut [
175/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
176/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
177/// ]
178/// );
179///
180/// let colors: &mut [PackedArgb] = vec.uints_as_mut();
181/// assert_eq!(
182/// colors,
183/// &mut [
184/// Srgba::new(0x17, 0xC6, 0x4C, 0xFF).into(),
185/// Srgba::new(0x5D, 0x12, 0xD6, 0xFF).into()
186/// ]
187/// );
188/// ```
189pub trait UintsAsMut<C: ?Sized> {
190 /// Cast this collection of unsigned integers into a mutable collection of colors.
191 fn uints_as_mut(&mut self) -> &mut C;
192}
193
194macro_rules! impl_uints_as {
195 ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
196 $(
197 impl<'a, C $(, $($ty_input)+)?> UintsAs<[C]> for $owning
198 where
199 C: UintCast,
200 {
201 #[inline]
202 fn uints_as(&self) -> &[C] {
203 from_uint_slice(self.as_ref())
204 }
205 }
206
207 impl<'a, C $(, $($ty_input)+)?> UintsAsMut<[C]> for $owning
208 where
209 C: UintCast,
210 {
211 #[inline]
212 fn uints_as_mut(&mut self) -> &mut [C] {
213 from_uint_slice_mut(self.as_mut())
214 }
215 }
216 )*
217 };
218}
219
220impl_uints_as!([C::Uint], [C::Uint; N] where (const N: usize));
221
222#[cfg(feature = "alloc")]
223impl_uints_as!(alloc::boxed::Box<[C::Uint]>, alloc::vec::Vec<C::Uint>);
224
225#[cfg(test)]
226mod test {
227 use crate::{rgb::PackedRgba, Srgba};
228
229 use super::{AsUints, AsUintsMut, UintsAs, UintsAsMut};
230
231 #[test]
232 fn as_uints() {
233 let slice: &[PackedRgba] = &[Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()];
234 let slice_mut: &mut [PackedRgba] =
235 &mut [Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()];
236 let mut slice_box: Box<[PackedRgba]> =
237 vec![Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()].into_boxed_slice();
238 let mut vec: Vec<PackedRgba> =
239 vec![Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()];
240 let mut array: [PackedRgba; 2] =
241 [Srgba::new(1, 2, 3, 4).into(), Srgba::new(5, 6, 7, 8).into()];
242
243 let _: &[u32] = slice.as_uints();
244 let _: &[u32] = slice_box.as_uints();
245 let _: &[u32] = vec.as_uints();
246 let _: &[u32] = array.as_uints();
247
248 let _: &mut [u32] = slice_mut.as_uints_mut();
249 let _: &mut [u32] = slice_box.as_uints_mut();
250 let _: &mut [u32] = vec.as_uints_mut();
251 let _: &mut [u32] = array.as_uints_mut();
252 }
253
254 #[test]
255 fn uints_as() {
256 let slice: &[u32] = &[0x01020304, 0x05060708];
257 let slice_mut: &mut [u32] = &mut [0x01020304, 0x05060708];
258 let mut slice_box: Box<[u32]> = vec![0x01020304, 0x05060708].into_boxed_slice();
259 let mut vec: Vec<u32> = vec![0x01020304, 0x05060708];
260 let mut array: [u32; 2] = [0x01020304, 0x05060708];
261
262 let _: &[PackedRgba] = slice.uints_as();
263 let _: &[PackedRgba] = slice_box.uints_as();
264 let _: &[PackedRgba] = vec.uints_as();
265 let _: &[PackedRgba] = array.uints_as();
266
267 let _: &mut [PackedRgba] = slice_mut.uints_as_mut();
268 let _: &mut [PackedRgba] = slice_box.uints_as_mut();
269 let _: &mut [PackedRgba] = vec.uints_as_mut();
270 let _: &mut [PackedRgba] = array.uints_as_mut();
271 }
272}