ratatui_core/style/
palette_conversion.rs

1//! Conversions from colors in the `palette` crate to [`Color`].
2
3use ::palette::LinSrgb;
4use ::palette::bool_mask::LazySelect;
5use ::palette::num::{Arithmetics, MulSub, PartialCmp, Powf, Real};
6use palette::Srgb;
7use palette::stimulus::IntoStimulus;
8
9use crate::style::Color;
10
11/// Convert an [`palette::Srgb`] color to a [`Color`].
12///
13/// # Examples
14///
15/// ```
16/// use palette::Srgb;
17/// use ratatui_core::style::Color;
18///
19/// let color = Color::from(Srgb::new(1.0f32, 0.0, 0.0));
20/// assert_eq!(color, Color::Rgb(255, 0, 0));
21/// ```
22impl<T: IntoStimulus<u8>> From<Srgb<T>> for Color {
23    fn from(color: Srgb<T>) -> Self {
24        let (red, green, blue) = color.into_format().into_components();
25        Self::Rgb(red, green, blue)
26    }
27}
28
29/// Convert a [`palette::LinSrgb`] color to a [`Color`].
30///
31/// Note: this conversion only works for floating point linear sRGB colors. If you have a linear
32/// sRGB color in another format, you need to convert it to floating point first.
33///
34/// # Examples
35///
36/// ```
37/// use palette::LinSrgb;
38/// use ratatui_core::style::Color;
39///
40/// let color = Color::from(LinSrgb::new(1.0f32, 0.0, 0.0));
41/// assert_eq!(color, Color::Rgb(255, 0, 0));
42/// ```
43impl<T: IntoStimulus<u8>> From<LinSrgb<T>> for Color
44where
45    T: Real + Powf + MulSub + Arithmetics + PartialCmp + Clone,
46    T::Mask: LazySelect<T>,
47{
48    fn from(color: LinSrgb<T>) -> Self {
49        let srgb_color = Srgb::<T>::from_linear(color);
50        Self::from(srgb_color)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn from_srgb() {
60        const RED: Color = Color::Rgb(255, 0, 0);
61        assert_eq!(Color::from(Srgb::new(255u8, 0, 0)), RED);
62        assert_eq!(Color::from(Srgb::new(65535u16, 0, 0)), RED);
63        assert_eq!(Color::from(Srgb::new(1.0f32, 0.0, 0.0)), RED);
64
65        assert_eq!(
66            Color::from(Srgb::new(0.5f32, 0.5, 0.5)),
67            Color::Rgb(128, 128, 128)
68        );
69    }
70
71    #[test]
72    fn from_lin_srgb() {
73        const RED: Color = Color::Rgb(255, 0, 0);
74        assert_eq!(Color::from(LinSrgb::new(1.0f32, 0.0, 0.0)), RED);
75        assert_eq!(Color::from(LinSrgb::new(1.0f64, 0.0, 0.0)), RED);
76
77        assert_eq!(
78            Color::from(LinSrgb::new(0.5f32, 0.5, 0.5)),
79            Color::Rgb(188, 188, 188)
80        );
81    }
82}