ascii_forge/renderer/
cell.rs

1use std::fmt::Display;
2
3use crate::prelude::*;
4use compact_str::{CompactString, ToCompactString};
5use unicode_width::UnicodeWidthStr;
6
7/// A cell that stores a symbol, and the style that will be applied to it.
8#[derive(Debug, Clone, Eq, PartialEq)]
9pub struct Cell {
10    text: CompactString,
11    style: ContentStyle,
12    width: u16,
13}
14
15impl Default for Cell {
16    fn default() -> Self {
17        Self::chr(' ')
18    }
19}
20
21impl Cell {
22    pub fn new<S: Into<ContentStyle>>(text: impl Into<CompactString>, style: S) -> Self {
23        let text = text.into();
24        Self {
25            width: text.width() as u16,
26            text,
27            style: style.into(),
28        }
29    }
30
31    pub fn string(string: impl AsRef<str>) -> Self {
32        let text = CompactString::new(string);
33        Self {
34            width: text.width() as u16,
35            text,
36            style: ContentStyle::default(),
37        }
38    }
39
40    pub fn chr(chr: char) -> Self {
41        let text = chr.to_compact_string();
42        Self {
43            width: text.width() as u16,
44            text,
45            style: ContentStyle::default(),
46        }
47    }
48
49    pub fn styled<D: Display>(content: StyledContent<D>) -> Self {
50        let text = CompactString::new(format!("{}", content.content()));
51        Self {
52            width: text.width() as u16,
53            text,
54            style: *content.style(),
55        }
56    }
57
58    pub fn width(&self) -> u16 {
59        self.width
60    }
61
62    pub fn is_empty(&self) -> bool {
63        self.text.trim().is_empty()
64    }
65
66    pub fn text(&self) -> &str {
67        &self.text
68    }
69
70    pub fn text_mut(&mut self) -> &mut CompactString {
71        &mut self.text
72    }
73
74    pub fn style(&self) -> &ContentStyle {
75        &self.style
76    }
77
78    pub fn style_mut(&mut self) -> &mut ContentStyle {
79        &mut self.style
80    }
81}
82
83impl Render for Cell {
84    fn render(&self, loc: crate::prelude::Vec2, buffer: &mut crate::prelude::Buffer) -> Vec2 {
85        buffer.set(loc, self.clone());
86        loc
87    }
88}
89
90macro_rules! str_impl {
91    ($($ty:ty)*) => {
92        $(
93            impl From<$ty> for Cell {
94                fn from(value: $ty) -> Self {
95                    Self::string(value)
96                }
97            }
98        )*
99    };
100}
101
102str_impl! {&str String}
103
104impl From<char> for Cell {
105    fn from(value: char) -> Self {
106        Self::chr(value)
107    }
108}
109
110impl<D: Display> From<StyledContent<D>> for Cell {
111    fn from(value: StyledContent<D>) -> Self {
112        Self::styled(value)
113    }
114}
115
116impl Display for Cell {
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        write!(f, "{}", StyledContent::new(self.style, &self.text))
119    }
120}