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
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct Style {
    pub bg: [u8; 3],
    pub 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 fn load(x: &[u8]) -> &[Cell] {
        unsafe {
            std::slice::from_raw_parts(
                x.as_ptr().cast(),
                x.len() / size_of::<Cell>(),
            )
        }
    }
}
impl Style {
    pub fn basic(self, c: char) -> Cell {
        Cell {
            style: self,
            letter: Some(c),
        }
    }
    pub fn empty(self) -> Cell {
        Cell {
            style: self,
            letter: None,
        }
    }
}

impl Default for Style {
    fn default() -> Self {
        Self {
            bg: [0; 3],
            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};
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;
}
#[derive(Clone, Copy, Default, PartialEq, Eq)]
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 BitOr<u8> for Style {
    type Output = Self;

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

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