retroglyph_core/grid/
trait_impls.rs1use super::{Grid, Pos, to_grixy_pos};
5#[cfg(test)]
6use crate::color::Style;
7use crate::tile::{Tile, TileFlags};
8use core::fmt;
9use core::ops::{Index, IndexMut};
10
11impl Index<Pos> for Grid {
12 type Output = Tile;
13
14 fn index(&self, pos: Pos) -> &Tile {
23 &self.layer0().buf[to_grixy_pos(pos)]
24 }
25}
26
27impl IndexMut<Pos> for Grid {
28 fn index_mut(&mut self, pos: Pos) -> &mut Tile {
36 let pos = to_grixy_pos(pos);
37 &mut self.layer0_mut().buf[pos]
38 }
39}
40
41impl fmt::Display for Grid {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 for y in 0..self.height() {
49 for x in 0..self.width() {
50 let tile = &self[Pos::new(x, y)];
51 let is_spacer = tile.flags.contains(TileFlags::WIDE_CHAR_SPACER);
52 let c = if is_spacer {
53 ' ' } else if tile.glyph == ' ' {
55 '·' } else {
57 tile.glyph
58 };
59 write!(f, "{c}")?;
60 }
61 writeln!(f)?;
62 }
63 Ok(())
64 }
65}
66
67impl fmt::Debug for Grid {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.debug_struct("Grid")
72 .field("width", &self.width)
73 .field("height", &self.height)
74 .field("max_layer", &self.max_layer)
75 .field("has_spans", &self.has_spans)
76 .finish_non_exhaustive()
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 #[should_panic(expected = "index out of bounds")]
86 fn index_panics_out_of_bounds() {
87 let grid = Grid::new(10, 10);
88 let _ = &grid[Pos::new(0, 10)];
89 }
90
91 #[test]
92 fn index_by_pos_reads_back_the_written_glyph() {
93 let mut grid = Grid::new(5, 5);
94 let pos = Pos::new(2, 3);
95 grid[pos] = Tile::default().with_glyph('Z');
96 assert_eq!(grid[pos].glyph(), 'Z');
97 }
98
99 #[test]
100 fn display_renders_glyphs_row_major_with_a_middle_dot_for_empty_cells() {
101 let mut grid = Grid::new(3, 2);
102 grid.put_tile(0, (0, 0), Tile::default().with_glyph('A'));
103
104 let s = alloc::format!("{grid}");
105 assert_eq!(s, "A··\n···\n");
106 }
107
108 #[cfg(feature = "egc")]
109 #[test]
110 fn display_wide_char_spacer_renders_as_a_plain_space() {
111 let mut grid = Grid::new(3, 1);
114 grid.write_grapheme(0, 0, 0, "\u{4e2d}", Style::default()); let s = alloc::format!("{grid}");
117 assert_eq!(s, "\u{4e2d} \u{b7}\n");
118 }
119
120 #[test]
121 fn debug_reports_layer_and_span_state() {
122 let mut grid = Grid::new(3, 2);
123 grid.put_tile(2, (0, 0), Tile::default().with_glyph('A'));
124 grid.write_span(0, 0, 0, &["hi"], Style::default());
125
126 let s = alloc::format!("{grid:?}");
127 assert!(s.contains("width: 3"));
128 assert!(s.contains("height: 2"));
129 assert!(s.contains("max_layer: 2"));
130 assert!(s.contains("has_spans: true"));
131 }
132}