use crate::TypeValueEncodable;
#[cfg(feature = "color-name")]
pub use color_name::css::colors::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
a: u8,
r: u8,
g: u8,
b: u8,
}
impl From<[u8; 3]> for Color {
fn from(value: [u8; 3]) -> Self {
Color {
a: 255,
r: value[0],
g: value[1],
b: value[2],
}
}
}
impl From<u32> for Color {
fn from(value: u32) -> Self {
let [a, r, g, b] = value.to_be_bytes();
if value & 0xFFFFFF == value {
Color { a: 255, r, g, b }
} else {
Color { a, r, g, b }
}
}
}
impl Color {
#[must_use]
pub fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
Self { a, r, g, b }
}
#[must_use]
pub fn with_alpha(&self, a: u8) -> Self {
Color { a, ..*self }
}
#[must_use]
pub fn with_red(&self, r: u8) -> Self {
Color { r, ..*self }
}
#[must_use]
pub fn with_green(&self, g: u8) -> Self {
Color { g, ..*self }
}
#[must_use]
pub fn with_blue(&self, b: u8) -> Self {
Color { b, ..*self }
}
#[must_use]
pub fn alpha(&self) -> u8 {
self.a
}
#[must_use]
pub fn red(&self) -> u8 {
self.r
}
#[must_use]
pub fn green(&self) -> u8 {
self.g
}
#[must_use]
pub fn blue(&self) -> u8 {
self.b
}
}
impl TypeValueEncodable for Color {
type Type = nvtx_sys::ColorType;
type Value = u32;
fn encode(&self) -> (Self::Type, Self::Value) {
let as_u32 = u32::from_be_bytes([self.a, self.r, self.g, self.b]);
(Self::Type::NVTX_COLOR_ARGB, as_u32)
}
fn default_encoding() -> (Self::Type, Self::Value) {
(Self::Type::NVTX_COLOR_UNKNOWN, 0)
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use crate::{common::TestUtils, TypeValueEncodable};
use super::Color;
#[test]
fn ctor() {
let color = Color::new(0xFF, 0xEE, 0xDD, 0xCC);
assert_eq!(color.a, 0xCC);
assert_eq!(color.r, 0xFF);
assert_eq!(color.g, 0xEE);
assert_eq!(color.b, 0xDD);
}
#[test]
fn accessors() {
let color = Color::new(0x12, 0x34, 0x56, 0x78);
assert_eq!(color.r, color.red());
assert_eq!(color.g, color.green());
assert_eq!(color.b, color.blue());
assert_eq!(color.a, color.alpha());
}
#[test]
fn from_u8_array() {
let arr: [u8; 3] = [0xAB, 0xCD, 0xEF];
let color = Color::from(arr);
assert_eq!(color.a, 0xFF);
assert_eq!(color.r, 0xAB);
assert_eq!(color.g, 0xCD);
assert_eq!(color.b, 0xEF);
}
#[test]
fn from_u32_mask_0xffffff() {
let color = Color::from(0xABCDEF);
assert_eq!(color.a, 0xFF);
assert_eq!(color.r, 0xAB);
assert_eq!(color.g, 0xCD);
assert_eq!(color.b, 0xEF);
}
#[test]
fn from_u32_mask_0xffffffff() {
let color = Color::from(0xFEDCBA98);
assert_eq!(color.a, 0xFE);
assert_eq!(color.r, 0xDC);
assert_eq!(color.g, 0xBA);
assert_eq!(color.b, 0x98);
}
#[test]
fn with() {
let black = Color::new(0, 0, 0, 0);
let red = Color::new(0xFF, 0, 0, 0);
let green = Color::new(0, 0xFF, 0, 0);
let blue = Color::new(0, 0, 0xFF, 0);
let transparent = Color::new(0, 0, 0, 0xFF);
assert_eq!(black.with_red(0xFF), red);
assert_eq!(black.with_green(0xFF), green);
assert_eq!(black.with_blue(0xFF), blue);
assert_eq!(black.with_alpha(0xFF), transparent);
}
#[test]
fn encode() {
let (r, g, b, a) = (0x12, 0x34, 0x56, 0x78);
let color = Color::new(r, g, b, a);
TestUtils::assert_color_encoding(&color, r, g, b, a);
}
#[test]
fn test_encode_default() {
let (t, v) = Color::default_encoding();
assert_eq!(t, nvtx_sys::ColorType::NVTX_COLOR_UNKNOWN);
assert_eq!(v, 0);
}
}