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}