fluent_ansi/colors/
simple.rs

1use core::fmt::Result;
2
3use crate::{
4    CodeWriter, ColorTarget,
5    color::{BasicColor, Color, IndexedColor, WriteColorCodes},
6    impl_macros::color_type::impl_color_type,
7};
8
9/// A simple color type representing the 16 basic terminal colors (8 basic colors + bright variants).
10///
11/// These colors are also available as associated [`BasicColor`] constants in the [`Color`](super::Color) enum, which
12/// can be turned into a [`SimpleColor`] value:
13///
14/// ```
15/// use fluent_ansi::{prelude::*, color::{BasicColor, SimpleColor}};
16///
17/// assert_eq!(Color::RED.to_simple_color(), SimpleColor::new(BasicColor::Red));
18/// assert_eq!(Color::RED.bright(), SimpleColor::new_bright(BasicColor::Red));
19/// ```
20///
21/// See Wikipedia's article on [3-bit and 4-bit colors ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit).
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub struct SimpleColor {
24    basic_color: BasicColor,
25    bright: bool,
26}
27
28impl SimpleColor {
29    /// Creates a new simple, non-bright color.
30    #[must_use]
31    pub const fn new(basic_color: BasicColor) -> Self {
32        Self {
33            basic_color,
34            bright: false,
35        }
36    }
37
38    /// Creates a new bright simple color.
39    #[must_use]
40    pub const fn new_bright(basic_color: BasicColor) -> Self {
41        Self::new(basic_color).bright()
42    }
43
44    /// Returns a bright variant of this simple color.
45    #[must_use]
46    pub const fn bright(self) -> Self {
47        Self {
48            bright: true,
49            ..self
50        }
51    }
52
53    /// Returns the basic color of this simple color.
54    #[must_use]
55    pub const fn get_basic_color(self) -> BasicColor {
56        self.basic_color
57    }
58
59    /// Returns whether this simple color is bright.
60    #[must_use]
61    pub const fn is_bright(self) -> bool {
62        self.bright
63    }
64}
65
66impl_color_type!(SimpleColor {
67    args: [self];
68    to_color: { Color::Simple(self) }
69});
70
71impl WriteColorCodes for SimpleColor {
72    fn write_color_codes(self, target: ColorTarget, writer: &mut CodeWriter) -> Result {
73        let offset = self.basic_color.code_offset();
74
75        match (target, self.bright) {
76            (ColorTarget::Foreground, false) => writer.write_code(30 + offset),
77            (ColorTarget::Background, false) => writer.write_code(40 + offset),
78            (ColorTarget::Foreground, true) => writer.write_code(90 + offset),
79            (ColorTarget::Background, true) => writer.write_code(100 + offset),
80            (ColorTarget::Underline, false) => {
81                IndexedColor(offset).write_color_codes(target, writer)
82            }
83            (ColorTarget::Underline, true) => {
84                IndexedColor(offset + 8).write_color_codes(target, writer)
85            }
86        }
87    }
88}