notcurses/color/
rgb.rs

1// notcurses::color::rgb
2//
3//!
4//
5
6use crate::sys::{
7    c_api::{NcRgb_u32, NcRgba_u32},
8    NcRgb, NcRgba,
9};
10
11/// A 24-bit RGB value.
12#[derive(Clone, Copy, Default, PartialEq, Eq)]
13pub struct Rgb(NcRgb);
14impl Rgb {
15    /// New const RGB color.
16    pub const fn new(r: u8, g: u8, b: u8) -> Self {
17        Self(NcRgb(
18            (r as NcRgb_u32) << 16 | (g as NcRgb_u32) << 8 | b as NcRgb_u32,
19        ))
20    }
21}
22
23/// A 32-bit RGBA value.
24#[derive(Clone, Copy, Default, PartialEq, Eq)]
25pub struct Rgba(NcRgba);
26impl Rgba {
27    /// New const RGBA color.
28    pub const fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
29        Self(NcRgba(
30            (a as NcRgba_u32) << 24
31                | (r as NcRgba_u32) << 16
32                | (g as NcRgba_u32) << 8
33                | b as NcRgba_u32,
34        ))
35    }
36}
37
38mod core_impls {
39    use super::{Rgb, Rgba};
40    use crate::sys::{
41        c_api::{NcRgb_u32, NcRgba_u32},
42        NcRgb, NcRgba,
43    };
44    use core::fmt;
45    use rgb::{RGB, RGBA};
46
47    impl fmt::Display for Rgb {
48        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49            write!(f, "{:06X}", self.0)
50        }
51    }
52    impl fmt::Debug for Rgb {
53        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54            write!(f, "Rgb({})", self.0)
55        }
56    }
57
58    impl fmt::Display for Rgba {
59        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60            write!(f, "{:08X}", self.0)
61        }
62    }
63    impl fmt::Debug for Rgba {
64        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65            write!(f, "Rgb({})", self.0)
66        }
67    }
68
69    //
70
71    impl From<NcRgb> for Rgb {
72        fn from(nc: NcRgb) -> Rgb {
73            Rgb(nc)
74        }
75    }
76    impl From<Rgb> for NcRgb {
77        fn from(rgb: Rgb) -> NcRgb {
78            rgb.0
79        }
80    }
81
82    impl From<NcRgba> for Rgba {
83        fn from(nc: NcRgba) -> Rgba {
84            Rgba(nc)
85        }
86    }
87    impl From<Rgba> for NcRgba {
88        fn from(rgba: Rgba) -> NcRgba {
89            rgba.0
90        }
91    }
92
93    //
94
95    impl From<NcRgb_u32> for Rgb {
96        fn from(ncu: NcRgb_u32) -> Rgb {
97            Rgb(NcRgb::from(ncu))
98        }
99    }
100    impl From<Rgb> for NcRgb_u32 {
101        fn from(rgb: Rgb) -> NcRgb_u32 {
102            rgb.0.into()
103        }
104    }
105
106    impl From<NcRgba_u32> for Rgba {
107        fn from(ncu: NcRgba_u32) -> Rgba {
108            Rgba(NcRgba::from(ncu))
109        }
110    }
111    impl From<Rgba> for NcRgba_u32 {
112        fn from(rgba: Rgba) -> NcRgba_u32 {
113            rgba.0.into()
114        }
115    }
116
117    //
118
119    impl From<[u8; 3]> for Rgb {
120        fn from(array: [u8; 3]) -> Self {
121            Rgb(array.into())
122        }
123    }
124    impl From<&[u8; 3]> for Rgb {
125        fn from(array: &[u8; 3]) -> Self {
126            Rgb(array.into())
127        }
128    }
129    impl From<Rgb> for [u8; 3] {
130        fn from(rgb: Rgb) -> Self {
131            rgb.0.into()
132        }
133    }
134    impl From<(u8, u8, u8)> for Rgb {
135        fn from(tuple: (u8, u8, u8)) -> Self {
136            Rgb(tuple.into())
137        }
138    }
139    impl From<Rgb> for (u8, u8, u8) {
140        fn from(rgb: Rgb) -> Self {
141            rgb.0.into()
142        }
143    }
144
145    impl From<[u8; 4]> for Rgba {
146        fn from(array: [u8; 4]) -> Self {
147            Rgba(array.into())
148        }
149    }
150    impl From<&[u8; 4]> for Rgba {
151        fn from(array: &[u8; 4]) -> Self {
152            Rgba(array.into())
153        }
154    }
155    impl From<Rgba> for [u8; 4] {
156        fn from(rgba: Rgba) -> Self {
157            rgba.0.into()
158        }
159    }
160    impl From<(u8, u8, u8, u8)> for Rgba {
161        fn from(tuple: (u8, u8, u8, u8)) -> Self {
162            Rgba(tuple.into())
163        }
164    }
165    impl From<Rgba> for (u8, u8, u8, u8) {
166        fn from(rgba: Rgba) -> Self {
167            rgba.0.into()
168        }
169    }
170
171    // between Rgb & Rgba
172
173    impl From<Rgb> for Rgba {
174        #[inline]
175        fn from(rgb: Rgb) -> Self {
176            let a: [u8; 3] = rgb.into();
177            [a[0], a[1], a[2], 255].into()
178        }
179    }
180    impl From<Rgba> for Rgb {
181        #[inline]
182        fn from(rgba: Rgba) -> Self {
183            let a: [u8; 4] = rgba.into();
184            [a[0], a[1], a[2]].into()
185        }
186    }
187
188    // for rgb crate
189
190    impl From<RGB<u8>> for Rgb {
191        fn from(item: RGB<u8>) -> Self {
192            Self::new(item.r, item.g, item.b)
193        }
194    }
195    impl From<Rgb> for RGB<u8> {
196        fn from(item: Rgb) -> Self {
197            let a: [u8; 3] = item.into();
198            Self::new(a[0], a[1], a[2])
199        }
200    }
201
202    impl From<RGBA<u8>> for Rgba {
203        fn from(item: RGBA<u8>) -> Self {
204            Self::new(item.r, item.g, item.b, item.a)
205        }
206    }
207    impl From<Rgba> for RGBA<u8> {
208        fn from(item: Rgba) -> Self {
209            let a: [u8; 4] = item.into();
210            Self::new(a[0], a[1], a[2], a[3])
211        }
212    }
213}