1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Effect {
    Bold,
    Dimmed,
    Italic,
    Underline,
    Blink,
    BlinkFast,
    Reversed,
    Hidden,
    Strikethrough,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum AnsiColor {
    Black,
    BrightBlack,

    Red,
    BrightRed,

    Green,
    BrightGreen,

    Yellow,
    BrightYellow,

    Blue,
    BrightBlue,

    Magenta,
    BrightMagenta,

    Cyan,
    BrightCyan,

    White,
    BrightWhite,
}

impl Into<Color> for AnsiColor {
    fn into(self) -> Color {
        Color::Ansi(self)
    }
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Color {
    Custom {
        r: u8,
        g: u8,
        b: u8,
    },
    Ansi(AnsiColor),
}

impl Color {
    pub fn rgb(r: u8, g: u8, b: u8) -> Self {
        Self::Custom {
            r,
            g,
            b,
        }
    }

    pub fn ansi(color: AnsiColor) -> Self {
        Self::Ansi(color)
    }
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
/// Style for content that appears in the frame buffer
pub struct Style {
    pub fg: Option<Color>,
    pub bg: Option<Color>,
    pub effects: Vec<Effect>,
}

impl Style {
    pub fn new() -> Self {
        Self {
            fg: None,
            bg: None,
            effects: Vec::new(),
        }
    }

    pub fn fg(mut self, color: Option<impl Into<Color>>) -> Self {
        self.fg = match color {
            Some(s) => Some(s.into()),
            None => None,
        };

        return self;
    }

    pub fn bg(mut self, color: Option<impl Into<Color>>) -> Self {
        self.bg = match color {
            Some(s) => Some(s.into()),
            None => None,
        };

        return self;
    }

    pub fn effect(mut self, effect: Effect) -> Self {
        self.effects.push(effect);

        return self;
    }

    pub fn effects(mut self, effects: &[Effect]) -> Self {
        for i in effects {
            self.effects.push(*i);
        }

        return self;
    }
}