Skip to main content

color_utils/
color.rs

1//! Color primitives
2
3use derive_more::{From, TryInto};
4use crate::constants::*;
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
7pub enum Color {
8  Named (Named),
9  Raw   ([u8; 4])
10}
11
12impl_newtype!{
13  Named { Monochrome, Hue }
14}
15impl_newtype!{
16  Terminal { Monochrome, Primary, Secondary }
17}
18impl_newtype!{
19  Hue { Primary, Secondary, Tertiary }
20}
21
22impl_primitive!{
23  Monochrome {
24    Black => BLACK,
25    White => WHITE,
26    Grey  => GREY
27  }
28}
29impl_primitive!{
30  Primary {
31    Red   => RED,
32    Green => GREEN,
33    Blue  => BLUE
34  }
35}
36impl_primitive!{
37  Secondary {
38    Cyan    => CYAN,
39    Yellow  => YELLOW,
40    Magenta => MAGENTA
41  }
42}
43impl_primitive!{
44  Tertiary {
45    Azure      => AZURE,
46    Viridian   => VIRIDIAN,
47    Chartreuse => CHARTREUSE,
48    Orange     => ORANGE,
49    Rose       => ROSE,
50    Violet     => VIOLET
51  }
52}
53
54impl Color {
55  pub const BLACK   : Self =
56    Color::Named (Named::Monochrome (Monochrome::Black));
57  pub const WHITE   : Self =
58    Color::Named (Named::Monochrome (Monochrome::White));
59  pub const GREY    : Self =
60    Color::Named (Named::Monochrome (Monochrome::Grey));
61  pub const RED     : Self =
62    Color::Named (Named::Hue (Hue::Primary (Primary::Red)));
63  pub const GREEN   : Self =
64    Color::Named (Named::Hue (Hue::Primary (Primary::Green)));
65  pub const BLUE    : Self =
66    Color::Named (Named::Hue (Hue::Primary (Primary::Blue)));
67  pub const CYAN    : Self =
68    Color::Named (Named::Hue (Hue::Secondary (Secondary::Cyan)));
69  pub const MAGENTA : Self =
70    Color::Named (Named::Hue (Hue::Secondary (Secondary::Magenta)));
71  pub const YELLOW  : Self =
72    Color::Named (Named::Hue (Hue::Secondary (Secondary::Yellow)));
73
74  pub fn raw (&self) -> [u8; 4] {
75    match self {
76      Color::Named (named) => (*named).into(),
77      Color::Raw   (raw)   => *raw
78    }
79  }
80
81  pub const fn named (&self) -> Option <Named> {
82    match self {
83      Color::Named (named) => Some (*named),
84      Color::Raw   (_)     => None
85    }
86  }
87}
88
89macro impl_primitive {
90  ( $primitive:ident {
91      $($color:ident => $value:ident),+
92    }
93  ) => {
94    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
95    pub enum $primitive {
96      $($color),+
97    }
98    impl From <$primitive> for [u8; 4] {
99      fn from (primitive : $primitive) -> [u8; 4] {
100        match primitive {
101          $($primitive::$color => $value),+
102        }
103      }
104    }
105  }
106}
107
108macro impl_newtype {
109  ( $newtype:ident {
110      $($colors:ident),+
111    }
112  ) => {
113    #[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
114    pub enum $newtype {
115      $($colors ($colors)),+
116    }
117    impl From <$newtype> for [u8; 4] {
118      fn from (newtype : $newtype) -> [u8; 4] {
119        match newtype {
120          $($newtype::$colors (colors) => colors.into()),+
121        }
122      }
123    }
124  }
125}