use derive_more::{From, TryInto};
use crate::constants::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
pub enum Color {
Named (Named),
Raw ([u8; 4])
}
impl_newtype!{
Named { Monochrome, Hue }
}
impl_newtype!{
Terminal { Monochrome, Primary, Secondary }
}
impl_newtype!{
Hue { Primary, Secondary, Tertiary }
}
impl_primitive!{
Monochrome {
Black => BLACK,
White => WHITE,
Grey => GREY
}
}
impl_primitive!{
Primary {
Red => RED,
Green => GREEN,
Blue => BLUE
}
}
impl_primitive!{
Secondary {
Cyan => CYAN,
Yellow => YELLOW,
Magenta => MAGENTA
}
}
impl_primitive!{
Tertiary {
Azure => AZURE,
Viridian => VIRIDIAN,
Chartreuse => CHARTREUSE,
Orange => ORANGE,
Rose => ROSE,
Violet => VIOLET
}
}
impl Color {
pub fn raw (&self) -> [u8; 4] {
match self {
Color::Named (named) => (*named).into(),
Color::Raw (raw) => *raw
}
}
pub const fn black() -> Self {
Color::Named (Named::Monochrome (Monochrome::Black))
}
pub const fn white() -> Self {
Color::Named (Named::Monochrome (Monochrome::White))
}
pub const fn grey() -> Self {
Color::Named (Named::Monochrome (Monochrome::Grey))
}
pub const fn red() -> Self {
Color::Named (Named::Hue (Hue::Primary (Primary::Red)))
}
pub const fn green() -> Self {
Color::Named (Named::Hue (Hue::Primary (Primary::Green)))
}
pub const fn blue() -> Self {
Color::Named (Named::Hue (Hue::Primary (Primary::Blue)))
}
pub const fn cyan() -> Self {
Color::Named (Named::Hue (Hue::Secondary (Secondary::Cyan)))
}
pub const fn magenta() -> Self {
Color::Named (Named::Hue (Hue::Secondary (Secondary::Magenta)))
}
pub const fn yellow() -> Self {
Color::Named (Named::Hue (Hue::Secondary (Secondary::Yellow)))
}
}
macro impl_primitive {
( $primitive:ident {
$($color:ident => $value:ident),+
}
) => {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum $primitive {
$($color),+
}
impl From <$primitive> for [u8; 4] {
fn from (primitive : $primitive) -> [u8; 4] {
match primitive {
$($primitive::$color => $value),+
}
}
}
}
}
macro impl_newtype {
( $newtype:ident {
$($colors:ident),+
}
) => {
#[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
pub enum $newtype {
$($colors ($colors)),+
}
impl From <$newtype> for [u8; 4] {
fn from (newtype : $newtype) -> [u8; 4] {
match newtype {
$($newtype::$colors (colors) => colors.into()),+
}
}
}
}
}