palette/convert/from_into_color_unclamped.rs
1pub use palette_derive::FromColorUnclamped;
2
3#[cfg(feature = "alloc")]
4use crate::cast::{self, ArrayCast};
5
6/// A trait for unchecked conversion of one color from another.
7///
8/// See [`FromColor`](crate::convert::FromColor) for a lossy version of this trait.
9/// See [`TryFromColor`](crate::convert::TryFromColor) for a trait that gives an error when the result
10/// is out of bounds.
11///
12/// See the [`convert`](crate::convert) module for how to implement `FromColorUnclamped` for
13/// custom colors.
14pub trait FromColorUnclamped<T>: Sized {
15 /// Convert from T. The resulting color might be invalid in its color space.
16 ///
17 /// ```
18 /// use palette::convert::FromColorUnclamped;
19 /// use palette::{IsWithinBounds, Lch, Srgb};
20 ///
21 /// let rgb = Srgb::from_color_unclamped(Lch::new(50.0f32, 100.0, -175.0));
22 /// assert!(!rgb.is_within_bounds());
23 /// ```
24 #[must_use]
25 fn from_color_unclamped(val: T) -> Self;
26}
27
28#[cfg(feature = "alloc")]
29impl<T, U> FromColorUnclamped<alloc::vec::Vec<T>> for alloc::vec::Vec<U>
30where
31 T: ArrayCast,
32 U: ArrayCast<Array = T::Array> + FromColorUnclamped<T>,
33{
34 /// Convert all colors in place, without reallocating.
35 ///
36 /// ```
37 /// use palette::{convert::FromColorUnclamped, SaturateAssign, Srgb, Lch};
38 ///
39 /// let srgb = vec![Srgb::new(0.8f32, 1.0, 0.2), Srgb::new(0.9, 0.1, 0.3)];
40 /// let mut lch = Vec::<Lch>::from_color_unclamped(srgb);
41 ///
42 /// lch.saturate_assign(0.1);
43 ///
44 /// let srgb = Vec::<Srgb>::from_color_unclamped(lch);
45 /// ```
46 #[inline]
47 fn from_color_unclamped(color: alloc::vec::Vec<T>) -> Self {
48 cast::map_vec_in_place(color, U::from_color_unclamped)
49 }
50}
51
52#[cfg(feature = "alloc")]
53impl<T, U> FromColorUnclamped<alloc::boxed::Box<[T]>> for alloc::boxed::Box<[U]>
54where
55 T: ArrayCast,
56 U: ArrayCast<Array = T::Array> + FromColorUnclamped<T>,
57{
58 /// Convert all colors in place, without reallocating.
59 ///
60 /// ```
61 /// use palette::{convert::FromColorUnclamped, SaturateAssign, Srgb, Lch};
62 ///
63 /// let srgb = vec![Srgb::new(0.8f32, 1.0, 0.2), Srgb::new(0.9, 0.1, 0.3)].into_boxed_slice();
64 /// let mut lch = Box::<[Lch]>::from_color_unclamped(srgb);
65 ///
66 /// lch.saturate_assign(0.1);
67 ///
68 /// let srgb = Box::<[Srgb]>::from_color_unclamped(lch);
69 /// ```
70 #[inline]
71 fn from_color_unclamped(color: alloc::boxed::Box<[T]>) -> Self {
72 cast::map_slice_box_in_place(color, U::from_color_unclamped)
73 }
74}
75
76/// A trait for unchecked conversion of a color into another.
77///
78/// `U: IntoColorUnclamped<T>` is implemented for every type `T: FromColorUnclamped<U>`.
79///
80/// See [`FromColorUnclamped`](crate::convert::FromColorUnclamped) for more details.
81pub trait IntoColorUnclamped<T>: Sized {
82 /// Convert into T. The resulting color might be invalid in its color space
83 ///
84 /// ```
85 /// use palette::convert::IntoColorUnclamped;
86 /// use palette::{IsWithinBounds, Lch, Srgb};
87 ///
88 ///let rgb: Srgb = Lch::new(50.0, 100.0, -175.0).into_color_unclamped();
89 ///assert!(!rgb.is_within_bounds());
90 ///```
91 #[must_use]
92 fn into_color_unclamped(self) -> T;
93}
94
95impl<T, U> IntoColorUnclamped<U> for T
96where
97 U: FromColorUnclamped<T>,
98{
99 #[inline]
100 fn into_color_unclamped(self) -> U {
101 U::from_color_unclamped(self)
102 }
103}