pub struct RGBA { pub r: u8, pub g: u8, pub b: u8, pub a: u8, } impl RGBA { const WHITE: RGBA = RGBA { r: 0xFF, g: 0xFF, b: 0xFF, a: 0xFF, }; const BLACK: RGBA = RGBA { r: 0, g: 0, b: 0, a: 0xFF, }; const CLEAR: RGBA = RGBA { r: 0, g: 0, b: 0, a: 0, }; pub fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self { RGBA { r, g, b, a } } pub fn rgb(r: u8, g: u8, b: u8) -> Self { Self::rgba(r, g, b, 255) } } impl From<RGBA> for i32 { fn from(value: RGBA) -> Self { i32::from_be_bytes(value.into()) } } impl From<i32> for RGBA { fn from(value: i32) -> Self { i32::to_be_bytes(value).into() } } impl From<RGBA> for u32 { fn from(value: RGBA) -> Self { u32::from_be_bytes(value.into()) } } impl From<u32> for RGBA { fn from(value: u32) -> Self { u32::to_be_bytes(value).into() } } impl From<[u8; 3]> for RGBA { fn from(value: [u8; 3]) -> Self { Self::rgb(value[0], value[1], value[2]) } } impl From<RGBA> for [u8; 3] { fn from(value: RGBA) -> Self { [value.r, value.g, value.b] } } impl From<[u8; 4]> for RGBA { fn from(value: [u8; 4]) -> Self { Self::rgba(value[0], value[1], value[2], value[3]) } } impl From<RGBA> for [u8; 4] { fn from(value: RGBA) -> Self { [value.r, value.g, value.b, value.a] } } impl From<(u8, u8, u8)> for RGBA { fn from(value: (u8, u8, u8)) -> Self { Self::rgb(value.0, value.1, value.2) } } impl From<RGBA> for (u8, u8, u8) { fn from(value: RGBA) -> Self { (value.r, value.g, value.b) } } impl From<(u8, u8, u8, u8)> for RGBA { fn from(value: (u8, u8, u8, u8)) -> Self { Self::rgba(value.0, value.1, value.2, value.3) } } impl From<RGBA> for (u8, u8, u8, u8) { fn from(value: RGBA) -> Self { (value.r, value.g, value.b, value.a) } } pub struct ColorPair { pub bg: RGBA, pub fg: RGBA, } impl ColorPair { pub fn new(bg: RGBA, fg: RGBA) -> Self { Self { bg, fg } } } impl<T1: Into<RGBA>, T2: Into<RGBA>> From<(T1, T2)> for ColorPair { fn from(value: (T1, T2)) -> Self { Self { bg: value.0.into(), fg: value.1.into(), } } }