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
120
121
122
123
124
125
126
127
128
129
130
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[repr(C)]
pub struct Style {
    pub bg: [u8; 3],
    pub fg: [u8; 3],
    pub secondary_color: [u8; 3],
    // one of [Style::BOLD]..
    pub flags: u8,
}
impl Hash for Cell {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.style.flags.hash(state);
        self.letter.hash(state);
    }
}
impl Cell {
    pub fn store(x: &[Cell]) -> &[u8] {
        unsafe {
            std::slice::from_raw_parts(
                x.as_ptr().cast(),
                x.len() * size_of::<Cell>(),
            )
        }
    }
    pub unsafe fn load(x: &[u8]) -> &[Cell] {
        std::slice::from_raw_parts(
            x.as_ptr().cast(),
            x.len() / size_of::<Cell>(),
        )
    }
}
impl Style {
    pub const fn basic(self, c: char) -> Cell {
        Cell {
            style: self,
            letter: Some(c),
        }
    }
    pub const fn empty(self) -> Cell {
        Cell {
            style: self,
            letter: None,
        }
    }
    pub const fn new(fg: [u8; 3], bg: [u8; 3]) -> Self {
        Self {
            fg,
            bg,
            secondary_color: fg,
            flags: 0,
        }
    }
}

impl const Default for Style {
    fn default() -> Self {
        Self {
            bg: [0; 3],
            fg: [255; 3],
            secondary_color: [255; 3],
            flags: 0,
        }
    }
}

use std::default::Default::default;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};

use serde::{Deserialize, Serialize};
impl Style {
    pub const BOLD: u8 = 1;
    pub const DIM: u8 = 1 << 1;
    pub const ITALIC: u8 = 1 << 2;
    pub const UNDERLINE: u8 = 1 << 3;
    pub const STRIKETHROUGH: u8 = 1 << 4;
    pub const UNDERCURL: u8 = 1 << 5;
    pub const USE_SECONDARY_COLOR: u8 = 1 << 7;
}
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive_const(Default)]
pub struct Cell {
    pub style: Style,
    pub letter: Option<char>,
}

impl Debug for Cell {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.letter.unwrap_or(' '))
    }
}
impl const BitOr<u8> for Style {
    type Output = Self;

    fn bitor(self, rhs: u8) -> Self::Output {
        Self {
            flags: self.flags | rhs,
            ..self
        }
    }
}
impl const BitOrAssign<(u8, [u8; 3])> for Style {
    fn bitor_assign(&mut self, (f, c): (u8, [u8; 3])) {
        self.flags |= f;
        self.fg = c;
    }
}
impl const BitAnd<(u8, [u8; 3])> for Style {
    type Output = Style;
    fn bitand(mut self, (flags, bg): (u8, [u8; 3])) -> Self::Output {
        self.flags |= flags;
        self.bg = bg;
        self
    }
}
impl const BitAndAssign<(u8, [u8; 3])> for Style {
    fn bitand_assign(&mut self, rhs: (u8, [u8; 3])) {
        *self = *self & rhs;
    }
}

impl Cell {
    pub const fn basic(c: char) -> Self {
        Self {
            letter: Some(c),
            ..default()
        }
    }
}