palette/cast/
from_into_components_traits.rs

1use core::{convert::Infallible, fmt::Debug};
2
3use crate::ArrayExt;
4
5use super::{
6    from_component_array, into_component_array, into_component_slice, into_component_slice_mut,
7    try_from_component_slice, try_from_component_slice_mut, ArrayCast, SliceCastError,
8};
9
10#[cfg(feature = "alloc")]
11use super::{
12    into_component_slice_box, into_component_vec, try_from_component_slice_box,
13    try_from_component_vec, BoxedSliceCastError, VecCastError,
14};
15
16/// Trait for trying to cast a collection of colors from a collection of color
17/// components without copying.
18///
19/// This trait is meant as a more convenient alternative to the free functions
20/// in [`cast`][crate::cast], to allow method chaining among other things.
21///
22/// ## Errors
23///
24/// The cast will return an error if the cast fails, such as when the length of
25/// the input is not a multiple of the color's array length.
26///
27/// ## Examples
28///
29/// ```
30/// use palette::{cast::TryFromComponents, Srgb};
31///
32/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
33/// let slice: &[_] = &[64, 139, 10, 93, 18, 214];
34/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214];
35/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
36///
37/// assert_eq!(
38///     <[Srgb<u8>; 2]>::try_from_components(array),
39///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)])
40/// );
41///
42/// assert_eq!(
43///     <&[Srgb<u8>]>::try_from_components(slice),
44///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_ref())
45/// );
46///
47/// assert_eq!(
48///     <&mut [Srgb<u8>]>::try_from_components(slice_mut),
49///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_mut())
50/// );
51///
52/// assert_eq!(
53///     Vec::<Srgb<u8>>::try_from_components(vec),
54///     Ok(vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)])
55/// );
56/// ```
57///
58/// Owning types can be cast as slices, too:
59///
60/// ```
61/// use palette::{cast::TryFromComponents, Srgb};
62///
63/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
64/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
65///
66/// assert_eq!(
67///     <&[Srgb<u8>]>::try_from_components(&array),
68///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_ref())
69/// );
70///
71/// assert_eq!(
72///     <&mut [Srgb<u8>]>::try_from_components(&mut vec),
73///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_mut())
74/// );
75/// ```
76///
77/// This produces an error:
78///
79/// ```
80/// use palette::{cast::TryFromComponents, Srgb};
81///
82/// let components = &[64, 139, 10, 93, 18]; // Not a multiple of 3
83/// assert!(<&[Srgb<u8>]>::try_from_components(components).is_err());
84/// ```
85pub trait TryFromComponents<C>: Sized {
86    /// The error for when `try_from_components` fails to cast.
87    type Error;
88
89    /// Try to cast a collection of color components into an collection of
90    /// colors.
91    ///
92    /// Return an error if the conversion can't be done, such as when the number
93    /// of items in `components` isn't a multiple of the number of components in
94    /// the color type.
95    fn try_from_components(components: C) -> Result<Self, Self::Error>;
96}
97
98impl<T, C, const N: usize, const M: usize> TryFromComponents<[T; N]> for [C; M]
99where
100    C: ArrayCast,
101    C::Array: ArrayExt<Item = T>,
102{
103    type Error = Infallible; // We don't provide a `try_*` option for arrays.
104
105    #[inline]
106    fn try_from_components(components: [T; N]) -> Result<Self, Self::Error> {
107        Ok(from_component_array(components))
108    }
109}
110
111macro_rules! impl_try_from_components_slice {
112    ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
113        $(
114            impl<'a, T, C $(, $($ty_input)+)?> TryFromComponents<&'a $owning> for &'a [C]
115            where
116                T: 'a,
117                C: ArrayCast,
118                C::Array: ArrayExt<Item = T>,
119            {
120                type Error = SliceCastError;
121
122                #[inline]
123                fn try_from_components(components: &'a $owning) -> Result<Self, Self::Error> {
124                    try_from_component_slice(components)
125                }
126            }
127
128            impl<'a, T, C $(, $($ty_input)+)?> TryFromComponents<&'a mut $owning> for &'a mut [C]
129            where
130                T: 'a,
131                C: ArrayCast,
132                C::Array: ArrayExt<Item = T>,
133            {
134                type Error = SliceCastError;
135
136                #[inline]
137                fn try_from_components(components: &'a mut $owning) -> Result<Self, Self::Error> {
138                    try_from_component_slice_mut(components)
139                }
140            }
141        )*
142    };
143}
144
145impl_try_from_components_slice!([T], [T; N] where (const N: usize));
146
147#[cfg(feature = "alloc")]
148impl_try_from_components_slice!(alloc::boxed::Box<[T]>, alloc::vec::Vec<T>);
149
150#[cfg(feature = "alloc")]
151impl<T, C> TryFromComponents<alloc::boxed::Box<[T]>> for alloc::boxed::Box<[C]>
152where
153    C: ArrayCast,
154    C::Array: ArrayExt<Item = T>,
155{
156    type Error = BoxedSliceCastError<T>;
157
158    #[inline]
159    fn try_from_components(components: alloc::boxed::Box<[T]>) -> Result<Self, Self::Error> {
160        try_from_component_slice_box(components)
161    }
162}
163
164#[cfg(feature = "alloc")]
165impl<T, C> TryFromComponents<alloc::vec::Vec<T>> for alloc::vec::Vec<C>
166where
167    C: ArrayCast,
168    C::Array: ArrayExt<Item = T>,
169{
170    type Error = VecCastError<T>;
171
172    #[inline]
173    fn try_from_components(components: alloc::vec::Vec<T>) -> Result<Self, Self::Error> {
174        try_from_component_vec(components)
175    }
176}
177
178/// Trait for casting a collection of colors from a collection of color
179/// components without copying.
180///
181/// This trait is meant as a more convenient alternative to the free functions
182/// in [`cast`][crate::cast], to allow method chaining among other things.
183///
184/// ## Panics
185///
186/// The cast will panic if the cast fails, such as when the length of the input
187/// is not a multiple of the color's array length.
188///
189/// ## Examples
190///
191/// ```
192/// use palette::{cast::FromComponents, Srgb};
193///
194/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
195/// let slice: &[_] = &[64, 139, 10, 93, 18, 214];
196/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214];
197/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
198///
199/// assert_eq!(
200///     <[Srgb<u8>; 2]>::from_components(array),
201///     [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
202/// );
203///
204/// assert_eq!(
205///     <&[Srgb<u8>]>::from_components(slice),
206///     [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
207/// );
208///
209/// assert_eq!(
210///     <&mut [Srgb<u8>]>::from_components(slice_mut),
211///     [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
212/// );
213///
214/// assert_eq!(
215///     Vec::<Srgb<u8>>::from_components(vec),
216///     vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
217/// );
218/// ```
219///
220/// Owning types can be cast as slices, too:
221///
222/// ```
223/// use palette::{cast::FromComponents, Srgb};
224///
225/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
226/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
227///
228/// assert_eq!(
229///     <&[Srgb<u8>]>::from_components(&array),
230///     [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
231/// );
232///
233/// assert_eq!(
234///     <&mut [Srgb<u8>]>::from_components(&mut vec),
235///     [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]
236/// );
237/// ```
238///
239/// This panics:
240///
241/// ```should_panic
242/// use palette::{cast::FromComponents, Srgb};
243///
244/// let components = &[64, 139, 10, 93, 18, 214, 0, 123]; // Not a multiple of 3
245/// <&[Srgb<u8>]>::from_components(components);
246/// ```
247pub trait FromComponents<C> {
248    /// Cast a collection of color components into an collection of colors.
249    ///
250    /// ## Panics
251    /// If the conversion can't be done, such as when the number of items in
252    /// `components` isn't a multiple of the number of components in the color
253    /// type.
254    fn from_components(components: C) -> Self;
255}
256
257impl<T, C> FromComponents<C> for T
258where
259    T: TryFromComponents<C>,
260    T::Error: Debug,
261{
262    #[inline]
263    fn from_components(components: C) -> Self {
264        Self::try_from_components(components).unwrap()
265    }
266}
267
268/// Trait for casting a collection of colors into a collection of color
269/// components without copying.
270///
271/// This trait is meant as a more convenient alternative to the free functions
272/// in [`cast`][crate::cast], to allow method chaining among other things.
273///
274/// ## Examples
275///
276/// ```
277/// use palette::{cast::IntoComponents, Srgb};
278///
279/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
280/// let slice: &[_] = &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
281/// let slice_mut: &mut [_] = &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
282/// let vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
283///
284/// assert_eq!(array.into_components(), [64, 139, 10, 93, 18, 214]);
285/// assert_eq!(slice.into_components(), [64, 139, 10, 93, 18, 214]);
286/// assert_eq!(slice_mut.into_components(), [64, 139, 10, 93, 18, 214]);
287/// assert_eq!(vec.into_components(), vec![64, 139, 10, 93, 18, 214]);
288/// ```
289///
290/// Owning types can be cast as slices, too:
291///
292/// ```
293/// use palette::{cast::IntoComponents, Srgb};
294///
295/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
296/// let mut vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
297///
298/// assert_eq!((&array).into_components(), [64, 139, 10, 93, 18, 214]);
299/// assert_eq!((&mut vec).into_components(), [64, 139, 10, 93, 18, 214]);
300/// ```
301pub trait IntoComponents<C> {
302    /// Cast this collection of colors into a collection of color components.
303    fn into_components(self) -> C;
304}
305
306impl<T, C, const N: usize, const M: usize> IntoComponents<[T; M]> for [C; N]
307where
308    C: ArrayCast,
309    C::Array: ArrayExt<Item = T>,
310{
311    #[inline]
312    fn into_components(self) -> [T; M] {
313        into_component_array(self)
314    }
315}
316
317macro_rules! impl_into_components_slice {
318    ($($owning:ty $(where ($($ty_input:tt)+))?),*) => {
319        $(
320            impl<'a, T, C $(, $($ty_input)+)?> IntoComponents<&'a [T]> for &'a $owning
321            where
322                T: 'a,
323                C: ArrayCast,
324                C::Array: ArrayExt<Item = T>,
325            {
326                #[inline]
327                fn into_components(self) -> &'a [T]  {
328                    into_component_slice(self)
329                }
330            }
331
332            impl<'a, T, C $(, $($ty_input)+)?> IntoComponents<&'a mut [T]> for &'a mut $owning
333            where
334                T: 'a,
335                C: ArrayCast,
336                C::Array: ArrayExt<Item = T>,
337            {
338                #[inline]
339                fn into_components(self) -> &'a mut [T] {
340                    into_component_slice_mut(self)
341                }
342            }
343        )*
344    };
345}
346
347impl_into_components_slice!([C], [C; N] where (const N: usize));
348
349#[cfg(feature = "alloc")]
350impl_into_components_slice!(alloc::boxed::Box<[C]>, alloc::vec::Vec<C>);
351
352#[cfg(feature = "alloc")]
353impl<T, C> IntoComponents<alloc::boxed::Box<[T]>> for alloc::boxed::Box<[C]>
354where
355    C: ArrayCast,
356    C::Array: ArrayExt<Item = T>,
357{
358    #[inline]
359    fn into_components(self) -> alloc::boxed::Box<[T]> {
360        into_component_slice_box(self)
361    }
362}
363
364#[cfg(feature = "alloc")]
365impl<T, C> IntoComponents<alloc::vec::Vec<T>> for alloc::vec::Vec<C>
366where
367    C: ArrayCast,
368    C::Array: ArrayExt<Item = T>,
369{
370    #[inline]
371    fn into_components(self) -> alloc::vec::Vec<T> {
372        into_component_vec(self)
373    }
374}
375
376/// Trait for casting a collection of color components into a collection of
377/// colors without copying.
378///
379/// This trait is meant as a more convenient alternative to the free functions
380/// in [`cast`][crate::cast], to allow method chaining among other things.
381///
382/// ## Examples
383///
384/// ```
385/// use palette::{cast::ComponentsFrom, Srgb};
386///
387/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
388/// let slice: &[_] = &[Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
389/// let slice_mut: &mut [_] = &mut [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
390/// let vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
391///
392/// assert_eq!(<[_; 6]>::components_from(array), [64, 139, 10, 93, 18, 214]);
393/// assert_eq!(<&[_]>::components_from(slice), [64, 139, 10, 93, 18, 214]);
394/// assert_eq!(<&mut [_]>::components_from(slice_mut), [64, 139, 10, 93, 18, 214]);
395/// assert_eq!(Vec::<_>::components_from(vec), vec![64, 139, 10, 93, 18, 214]);
396/// ```
397///
398/// Owning types can be cast as slices, too:
399///
400/// ```
401/// use palette::{cast::ComponentsFrom, Srgb};
402///
403/// let array: [_; 2] = [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
404/// let mut vec: Vec<_> = vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)];
405///
406/// assert_eq!(<&[_]>::components_from(&array), [64, 139, 10, 93, 18, 214]);
407/// assert_eq!(<&mut [_]>::components_from(&mut vec), [64, 139, 10, 93, 18, 214]);
408/// ```
409pub trait ComponentsFrom<C> {
410    /// Cast a collection of colors into a collection of color components.
411    fn components_from(colors: C) -> Self;
412}
413
414impl<T, C> ComponentsFrom<C> for T
415where
416    C: IntoComponents<T>,
417{
418    #[inline]
419    fn components_from(colors: C) -> Self {
420        colors.into_components()
421    }
422}
423
424/// Trait for trying to cast a collection of color components from a collection
425/// of colors without copying.
426///
427/// This trait is meant as a more convenient alternative to the free functions
428/// in [`cast`][crate::cast], to allow method chaining among other things.
429///
430/// ## Errors
431///
432/// The cast will return an error if the cast fails, such as when the length of
433/// the input is not a multiple of the color's array length.
434///
435/// ## Examples
436///
437/// ```
438/// use palette::{cast::TryComponentsInto, Srgb};
439///
440/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
441/// let slice: &[_] = &[64, 139, 10, 93, 18, 214];
442/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214];
443/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
444///
445/// assert_eq!(
446///     array.try_components_into(),
447///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)])
448/// );
449///
450/// assert_eq!(
451///     slice.try_components_into(),
452///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_ref())
453/// );
454///
455/// assert_eq!(
456///     slice_mut.try_components_into(),
457///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_mut())
458/// );
459///
460/// assert_eq!(
461///     vec.try_components_into(),
462///     Ok(vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)])
463/// );
464/// ```
465///
466/// Owning types can be cast as slices, too:
467///
468/// ```
469/// use palette::{cast::TryComponentsInto, Srgb};
470///
471/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
472/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
473///
474/// assert_eq!(
475///     (&array).try_components_into(),
476///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_ref())
477/// );
478///
479/// assert_eq!(
480///     (&mut vec).try_components_into(),
481///     Ok([Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)].as_mut())
482/// );
483/// ```
484///
485/// This produces an error:
486///
487/// ```
488/// use palette::{cast::TryComponentsInto, Srgb};
489///
490/// let components = &[64, 139, 10, 93, 18]; // Not a multiple of 3
491/// let colors: Result<&[Srgb<u8>], _> = components.try_components_into();
492/// assert!(colors.is_err());
493/// ```
494pub trait TryComponentsInto<C>: Sized {
495    /// The error for when `try_into_colors` fails to cast.
496    type Error;
497
498    /// Try to cast this collection of color components into a collection of
499    /// colors.
500    ///
501    /// Return an error if the conversion can't be done, such as when the number
502    /// of items in `self` isn't a multiple of the number of components in the
503    /// color type.
504    fn try_components_into(self) -> Result<C, Self::Error>;
505}
506
507/// Trait for casting a collection of color components from a collection of
508/// colors without copying.
509///
510/// This trait is meant as a more convenient alternative to the free functions
511/// in [`cast`][crate::cast], to allow method chaining among other things.
512///
513/// ## Panics
514///
515/// The cast will panic if the cast fails, such as when the length of the input
516/// is not a multiple of the color's array length.
517///
518/// ## Examples
519///
520/// ```
521/// use palette::{cast::ComponentsInto, Srgb};
522///
523/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
524/// let slice: &[_] = &[64, 139, 10, 93, 18, 214];
525/// let slice_mut: &mut [_] = &mut [64, 139, 10, 93, 18, 214];
526/// let vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
527///
528/// let colors: [Srgb<u8>; 2] = array.components_into();
529/// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
530///
531/// let colors: &[Srgb<u8>] = slice.components_into();
532/// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
533///
534/// let colors: &mut [Srgb<u8>] = slice_mut.components_into();
535/// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
536///
537/// let colors: Vec<Srgb<u8>> = vec.components_into();
538/// assert_eq!(colors, vec![Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
539/// ```
540///
541/// Owning types can be cast as slices, too:
542///
543/// ```
544/// use palette::{cast::ComponentsInto, Srgb};
545///
546/// let array: [_; 6] = [64, 139, 10, 93, 18, 214];
547/// let mut vec: Vec<_> = vec![64, 139, 10, 93, 18, 214];
548///
549/// let colors: &[Srgb<u8>] = (&array).components_into();
550/// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
551///
552/// let colors: &mut [Srgb<u8>] = (&mut vec).components_into();
553/// assert_eq!(colors, [Srgb::new(64u8, 139, 10), Srgb::new(93, 18, 214)]);
554/// ```
555///
556/// This panics:
557///
558/// ```should_panic
559/// use palette::{cast::ComponentsInto, Srgb};
560///
561/// let components = &[64, 139, 10, 93, 18, 214, 0, 123]; // Not a multiple of 3
562/// let colors: &[Srgb<u8>] = components.components_into();
563/// ```
564pub trait ComponentsInto<C> {
565    /// Cast this collection of color components into a collection of colors.
566    ///
567    /// ## Panics
568    /// If the conversion can't be done, such as when the number of items in
569    /// `self` isn't a multiple of the number of components in the color type.
570    fn components_into(self) -> C;
571}
572
573impl<T, C> ComponentsInto<C> for T
574where
575    T: TryComponentsInto<C>,
576    T::Error: Debug,
577{
578    #[inline]
579    fn components_into(self) -> C {
580        self.try_components_into().unwrap()
581    }
582}
583
584impl<T, C> TryComponentsInto<C> for T
585where
586    C: TryFromComponents<T>,
587{
588    type Error = C::Error;
589
590    #[inline]
591    fn try_components_into(self) -> Result<C, Self::Error> {
592        C::try_from_components(self)
593    }
594}
595
596#[cfg(test)]
597mod test {
598    use crate::Srgb;
599
600    use super::{
601        ComponentsFrom, ComponentsInto, FromComponents, IntoComponents, TryComponentsInto,
602        TryFromComponents,
603    };
604
605    #[test]
606    fn try_from_components() {
607        let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
608        let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
609        let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
610
611        let _ = <&[Srgb<u8>]>::try_from_components(slice).unwrap();
612        let _ = <&[Srgb<u8>]>::try_from_components(&array).unwrap();
613
614        let _ = <&mut [Srgb<u8>]>::try_from_components(slice_mut).unwrap();
615        let _ = <&mut [Srgb<u8>]>::try_from_components(&mut array).unwrap();
616
617        let _ = <[Srgb<u8>; 2]>::try_from_components(array).unwrap();
618    }
619
620    #[cfg(feature = "alloc")]
621    #[test]
622    fn try_from_components_alloc() {
623        let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
624        let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
625
626        let _ = <&[Srgb<u8>]>::try_from_components(&slice_box).unwrap();
627        let _ = <&[Srgb<u8>]>::try_from_components(&vec).unwrap();
628
629        let _ = <&mut [Srgb<u8>]>::try_from_components(&mut slice_box).unwrap();
630        let _ = <&mut [Srgb<u8>]>::try_from_components(&mut vec).unwrap();
631
632        let _ = Box::<[Srgb<u8>]>::try_from_components(slice_box).unwrap();
633        let _ = Vec::<Srgb<u8>>::try_from_components(vec).unwrap();
634    }
635
636    #[test]
637    fn try_components_into() {
638        let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
639        let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
640        let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
641
642        let _: &[Srgb<u8>] = slice.try_components_into().unwrap();
643        let _: &[Srgb<u8>] = (&array).try_components_into().unwrap();
644
645        let _: &mut [Srgb<u8>] = slice_mut.try_components_into().unwrap();
646        let _: &mut [Srgb<u8>] = (&mut array).try_components_into().unwrap();
647
648        let _: [Srgb<u8>; 2] = array.try_components_into().unwrap();
649    }
650
651    #[cfg(feature = "alloc")]
652    #[test]
653    fn try_components_into_alloc() {
654        let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
655        let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
656
657        let _: &[Srgb<u8>] = (&slice_box).try_components_into().unwrap();
658        let _: &[Srgb<u8>] = (&vec).try_components_into().unwrap();
659
660        let _: &mut [Srgb<u8>] = (&mut slice_box).try_components_into().unwrap();
661        let _: &mut [Srgb<u8>] = (&mut vec).try_components_into().unwrap();
662
663        let _: Box<[Srgb<u8>]> = slice_box.try_components_into().unwrap();
664        let _: Vec<Srgb<u8>> = vec.try_components_into().unwrap();
665    }
666
667    #[test]
668    fn from_components() {
669        let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
670        let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
671        let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
672
673        let _ = <&[Srgb<u8>]>::from_components(slice);
674        let _ = <&[Srgb<u8>]>::from_components(&array);
675
676        let _ = <&mut [Srgb<u8>]>::from_components(slice_mut);
677        let _ = <&mut [Srgb<u8>]>::from_components(&mut array);
678
679        let _ = <[Srgb<u8>; 2]>::from_components(array);
680    }
681
682    #[cfg(feature = "alloc")]
683    #[test]
684    fn from_components_alloc() {
685        let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
686        let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
687
688        let _ = <&[Srgb<u8>]>::from_components(&slice_box);
689        let _ = <&[Srgb<u8>]>::from_components(&vec);
690
691        let _ = <&mut [Srgb<u8>]>::from_components(&mut slice_box);
692        let _ = <&mut [Srgb<u8>]>::from_components(&mut vec);
693
694        let _ = Box::<[Srgb<u8>]>::from_components(slice_box);
695        let _ = Vec::<Srgb<u8>>::from_components(vec);
696    }
697
698    #[test]
699    fn components_into() {
700        let slice: &[u8] = &[1, 2, 3, 4, 5, 6];
701        let slice_mut: &mut [u8] = &mut [1, 2, 3, 4, 5, 6];
702        let mut array: [u8; 6] = [1, 2, 3, 4, 5, 6];
703
704        let _: &[Srgb<u8>] = slice.components_into();
705        let _: &[Srgb<u8>] = (&array).components_into();
706
707        let _: &mut [Srgb<u8>] = slice_mut.components_into();
708        let _: &mut [Srgb<u8>] = (&mut array).components_into();
709
710        let _: [Srgb<u8>; 2] = array.components_into();
711    }
712
713    #[cfg(feature = "alloc")]
714    #[test]
715    fn components_into_alloc() {
716        let mut slice_box: Box<[u8]> = vec![1, 2, 3, 4, 5, 6].into_boxed_slice();
717        let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];
718
719        let _: &[Srgb<u8>] = (&slice_box).components_into();
720        let _: &[Srgb<u8>] = (&vec).components_into();
721
722        let _: &mut [Srgb<u8>] = (&mut slice_box).components_into();
723        let _: &mut [Srgb<u8>] = (&mut vec).components_into();
724
725        let _: Box<[Srgb<u8>]> = slice_box.components_into();
726        let _: Vec<Srgb<u8>> = vec.components_into();
727    }
728
729    #[test]
730    fn into_components() {
731        let slice: &[Srgb<u8>] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
732        let slice_mut: &mut [Srgb<u8>] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
733        let mut array: [Srgb<u8>; 2] = [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
734
735        let _: &[u8] = slice.into_components();
736        let _: &[u8] = (&array).into_components();
737
738        let _: &mut [u8] = slice_mut.into_components();
739        let _: &mut [u8] = (&mut array).into_components();
740
741        let _: [u8; 6] = array.into_components();
742    }
743
744    #[cfg(feature = "alloc")]
745    #[test]
746    fn into_components_alloc() {
747        let mut slice_box: Box<[Srgb<u8>]> =
748            vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice();
749        let mut vec: Vec<Srgb<u8>> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
750
751        let _: &[u8] = (&slice_box).into_components();
752        let _: &[u8] = (&vec).into_components();
753
754        let _: &mut [u8] = (&mut slice_box).into_components();
755        let _: &mut [u8] = (&mut vec).into_components();
756
757        let _: Box<[u8]> = slice_box.into_components();
758        let _: Vec<u8> = vec.into_components();
759    }
760
761    #[test]
762    fn components_from() {
763        let slice: &[Srgb<u8>] = &[Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
764        let slice_mut: &mut [Srgb<u8>] = &mut [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
765        let mut array: [Srgb<u8>; 2] = [Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
766
767        let _ = <&[u8]>::components_from(slice);
768        let _ = <&[u8]>::components_from(&array);
769
770        let _ = <&mut [u8]>::components_from(slice_mut);
771        let _ = <&mut [u8]>::components_from(&mut array);
772
773        let _ = <[u8; 6]>::components_from(array);
774    }
775
776    #[cfg(feature = "alloc")]
777    #[test]
778    fn components_from_alloc() {
779        let mut slice_box: Box<[Srgb<u8>]> =
780            vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)].into_boxed_slice();
781        let mut vec: Vec<Srgb<u8>> = vec![Srgb::new(1, 2, 3), Srgb::new(4, 5, 6)];
782
783        let _ = <&[u8]>::components_from(&slice_box);
784        let _ = <&[u8]>::components_from(&vec);
785
786        let _ = <&mut [u8]>::components_from(&mut slice_box);
787        let _ = <&mut [u8]>::components_from(&mut vec);
788
789        let _ = Box::<[u8]>::components_from(slice_box);
790        let _ = Vec::<u8>::components_from(vec);
791    }
792}