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,
        }
    }
}

const impl 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(' '))
    }
}
const impl BitOr<u8> for Style {
    type Output = Self;

    fn bitor(self, rhs: u8) -> Self::Output {
        Self {
            flags: self.flags | rhs,
            ..self
        }
    }
}
const impl BitOrAssign<(u8, [u8; 3])> for Style {
    fn bitor_assign(&mut self, (f, c): (u8, [u8; 3])) {
        self.flags |= f;
        self.fg = c;
    }
}
const impl 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
    }
}
const impl 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()
        }
    }
}