1use std::iter::once;
2
3pub struct Buffer {
4 start_x: usize,
5 start_y: usize,
6 grid: Vec<Vec<char>>,
7}
8
9impl Buffer {
10 pub fn new() -> Self {
11 Self {
12 start_x: 0,
13 start_y: 0,
14 grid: Vec::new(),
15 }
16 }
17
18 pub fn new_frame(&mut self) {
19 self.start_x = 0;
20 self.start_y = 0;
21 self.grid.clear();
22 }
23
24 pub fn new_frame_bounded(&mut self, start_x: usize, start_y: usize) {
25 self.start_x = start_x;
26 self.start_y = start_y;
27 self.grid.clear();
28 }
29
30 pub fn get_point(&self, x: usize, y: usize) -> char {
31 let x = x - self.start_x;
32 let y = y - self.start_y;
33 *self.grid.get(y).and_then(|y| y.get(x)).unwrap_or(&' ')
34 }
35
36 pub fn render_point(&mut self, x: usize, y: usize, c: char) {
37 let x = x - self.start_x;
38 let y = y - self.start_y;
39
40 if self.grid.len() < y + 1 {
41 self.grid.resize(y + 1, Vec::new());
42 }
43 let row = &mut self.grid[y];
44 if row.len() < x + 1 {
45 row.resize(x + 1, ' ');
46 }
47 row[x] = c;
48 }
49
50 pub fn into_inner(self) -> Vec<Vec<char>> { self.grid }
51
52 pub fn output(&self, width: usize) -> Vec<String> {
53 self.grid
54 .iter()
55 .map(|line| {
56 line.iter()
57 .copied()
58 .chain(once(' ').cycle())
59 .take(width)
60 .collect::<String>()
61 })
62 .collect::<Vec<_>>()
63 }
64}