use core::fmt::Result;
use crate::{CodeWriter, ColorTarget};
pub use basic::*;
pub use color_kind::*;
pub use indexed::*;
pub use rgb::*;
pub use simple::*;
mod basic;
mod color_kind;
mod indexed;
mod rgb;
mod simple;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Color {
Simple(SimpleColor),
Indexed(IndexedColor),
RGB(RGBColor),
}
impl Color {
pub const BLACK: BasicColor = BasicColor::Black;
pub const RED: BasicColor = BasicColor::Red;
pub const GREEN: BasicColor = BasicColor::Green;
pub const YELLOW: BasicColor = BasicColor::Yellow;
pub const BLUE: BasicColor = BasicColor::Blue;
pub const MAGENTA: BasicColor = BasicColor::Magenta;
pub const CYAN: BasicColor = BasicColor::Cyan;
pub const WHITE: BasicColor = BasicColor::White;
#[must_use]
pub const fn indexed(value: u8) -> IndexedColor {
IndexedColor::new(value)
}
#[must_use]
pub const fn rgb(r: u8, g: u8, b: u8) -> RGBColor {
RGBColor::new(r, g, b)
}
#[must_use]
pub const fn none() -> Option<Color> {
None
}
}
impl WriteColorCodes for Color {
fn write_color_codes(self, target: ColorTarget, writer: &mut CodeWriter) -> Result {
match self {
Color::Simple(simple) => simple.write_color_codes(target, writer),
Color::Indexed(indexed) => indexed.write_color_codes(target, writer),
Color::RGB(rgb) => rgb.write_color_codes(target, writer),
}
}
}
impl From<BasicColor> for Color {
fn from(basic: BasicColor) -> Self {
Color::Simple(basic.to_simple_color())
}
}
impl From<SimpleColor> for Color {
fn from(simple: SimpleColor) -> Self {
Color::Simple(simple)
}
}
impl From<IndexedColor> for Color {
fn from(indexed: IndexedColor) -> Self {
Color::Indexed(indexed)
}
}
impl From<RGBColor> for Color {
fn from(rgb: RGBColor) -> Self {
Color::RGB(rgb)
}
}
macro_rules! impl_reflexive_partial_eq {
($stricter:ident :: $method:ident () -> $general:ty) => {
impl PartialEq<$stricter> for $general {
fn eq(&self, other: &$stricter) -> bool {
*self == other.$method()
}
}
impl PartialEq<$general> for $stricter {
fn eq(&self, other: &$general) -> bool {
self.$method() == *other
}
}
};
}
impl_reflexive_partial_eq!(BasicColor::to_color() -> Color);
impl_reflexive_partial_eq!(SimpleColor::to_color() -> Color);
impl_reflexive_partial_eq!(IndexedColor::to_color() -> Color);
impl_reflexive_partial_eq!(RGBColor::to_color() -> Color);
impl_reflexive_partial_eq!(BasicColor::to_simple_color() -> SimpleColor);
#[cfg(test)]
mod tests {
use crate::{TargetedColor, test_to_style_set_methods_with_foreground_assumed};
use super::*;
test_to_style_set_methods_with_foreground_assumed!(Color::Simple(SimpleColor::new(
BasicColor::Red
)));
#[test]
fn shortcuts() {
assert_eq!(Color::BLACK, BasicColor::Black);
assert_eq!(Color::RED, BasicColor::Red);
assert_eq!(Color::GREEN, BasicColor::Green);
assert_eq!(Color::YELLOW, BasicColor::Yellow);
assert_eq!(Color::BLUE, BasicColor::Blue);
assert_eq!(Color::MAGENTA, BasicColor::Magenta);
assert_eq!(Color::CYAN, BasicColor::Cyan);
assert_eq!(Color::WHITE, BasicColor::White);
assert_eq!(Color::indexed(127), IndexedColor(127));
assert_eq!(Color::rgb(0, 128, 255), RGBColor::new(0, 128, 255));
}
#[test]
fn for_fg() {
let color = BasicColor::Red.to_color();
assert_eq!(
color.for_fg(),
TargetedColor::new(color, ColorTarget::Foreground)
);
assert_eq!(
color.for_target(ColorTarget::Foreground),
TargetedColor::new(color, ColorTarget::Foreground)
);
}
#[test]
fn for_bg() {
let color = BasicColor::Red.to_color();
assert_eq!(
color.for_bg(),
TargetedColor::new(color, ColorTarget::Background)
);
assert_eq!(
color.for_target(ColorTarget::Background),
TargetedColor::new(color, ColorTarget::Background)
);
}
#[test]
fn from_basic_color() {
assert_eq!(
Color::from(BasicColor::Red),
Color::Simple(SimpleColor::new(BasicColor::Red))
);
}
#[test]
fn from_simple_color() {
assert_eq!(
Color::from(SimpleColor::new(BasicColor::Red)),
Color::Simple(SimpleColor::new(BasicColor::Red))
);
}
#[test]
fn from_indexed_color() {
assert_eq!(
Color::from(IndexedColor(7)),
Color::Indexed(IndexedColor(7))
);
}
#[test]
fn from_rgb() {
assert_eq!(
Color::from(RGBColor::new(0, 128, 255)),
Color::RGB(RGBColor::new(0, 128, 255))
);
}
#[test]
fn eq() {
macro_rules! assert_colors_eq {
($ty1:ty, $ty2:ty; $expr1:expr, $expr2:expr, ) => {{
let color1: $ty1 = $expr1;
let color2: $ty2 = $expr2;
assert_eq!(
color1,
color2,
"{} x {}",
stringify!($ty1),
stringify!($ty2)
);
assert_eq!(
color2,
color1,
"{} x {}",
stringify!($ty2),
stringify!($ty1)
);
}};
}
macro_rules! assert_colors_ne {
($ty1:ty, $ty2:ty; $expr1:expr, $expr2:expr, ) => {{
let color1: $ty1 = $expr1;
let color2: $ty2 = $expr2;
assert_ne!(
color1,
color2,
"{} x {}",
stringify!($ty1),
stringify!($ty2)
);
assert_ne!(
color2,
color1,
"{} x {}",
stringify!($ty2),
stringify!($ty1)
);
}};
}
let basic_color = BasicColor::Red;
let simple_color = BasicColor::Red.to_simple_color();
let indexed_color = IndexedColor::new(128);
let rgb_color = RGBColor::new(0, 128, 255);
let other_basic_color = BasicColor::Green;
let other_simple_color = BasicColor::Green.to_simple_color();
let other_indexed_color = IndexedColor::new(33);
let other_rgb_color = RGBColor::new(33, 133, 235);
assert_colors_eq!(Color, BasicColor;
basic_color.to_color(),
basic_color,
);
assert_colors_ne!(Color, BasicColor;
other_basic_color.to_color(),
basic_color,
);
assert_colors_ne!(Color, BasicColor;
indexed_color.to_color(),
basic_color,
);
assert_colors_eq!(Color, SimpleColor;
simple_color.to_color(),
simple_color,
);
assert_colors_ne!(Color, SimpleColor;
other_simple_color.to_color(),
simple_color,
);
assert_colors_ne!(Color, SimpleColor;
indexed_color.to_color(),
simple_color,
);
assert_colors_eq!(Color, IndexedColor;
indexed_color.to_color(),
indexed_color,
);
assert_colors_ne!(Color, IndexedColor;
other_indexed_color.to_color(),
indexed_color,
);
assert_colors_ne!(Color, IndexedColor;
rgb_color.to_color(),
indexed_color,
);
assert_colors_eq!(Color, RGBColor;
rgb_color.to_color(),
rgb_color,
);
assert_colors_ne!(Color, RGBColor;
other_rgb_color.to_color(),
rgb_color,
);
assert_colors_ne!(Color, RGBColor;
basic_color.to_color(),
rgb_color,
);
assert_colors_eq!(SimpleColor, BasicColor;
basic_color.to_simple_color(),
basic_color,
);
assert_colors_ne!(SimpleColor, BasicColor;
other_basic_color.to_simple_color(),
basic_color,
);
assert_colors_ne!(SimpleColor, BasicColor;
basic_color.bright(),
basic_color,
);
}
}