1use crate::ansi::Color;
5use crate::render::Cell;
6use std::io::{self, Write};
7
8pub fn write_grid<W: Write>(out: &mut W, grid: &[Vec<Cell>], color: bool) -> io::Result<()> {
12 for row in grid {
13 for cell in row {
14 match cell {
15 Cell::Char { ch, style, .. } => {
16 if color {
17 if let Some(Color::Rgb(r, g, b)) = style.fg {
18 write!(out, "\x1b[38;2;{r};{g};{b}m")?;
19 }
20 if let Some(Color::Rgb(r, g, b)) = style.bg {
21 write!(out, "\x1b[48;2;{r};{g};{b}m")?;
22 }
23 }
24 write!(out, "{ch}")?;
25 }
26 Cell::Continuation => {}
27 Cell::Empty => write!(out, " ")?,
28 }
29 }
30 if color { write!(out, "\x1b[0m")?; }
31 writeln!(out)?;
32 }
33 Ok(())
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use crate::ansi::Style;
40
41 fn ch(c: char, fg: Option<Color>) -> Cell {
42 Cell::Char { ch: c, width: 1, style: Style { fg, bg: None, ..Default::default() }, hyperlink: None }
43 }
44
45 #[test]
46 fn plain_writes_chars_only() {
47 let grid = vec![vec![ch('@', Some(Color::Rgb(1, 2, 3))), ch('.', None)]];
48 let mut buf = Vec::new();
49 write_grid(&mut buf, &grid, false).unwrap();
50 assert_eq!(String::from_utf8(buf).unwrap(), "@.\n");
51 }
52
53 #[test]
54 fn color_emits_truecolor_sgr_and_reset() {
55 let grid = vec![vec![ch('@', Some(Color::Rgb(10, 20, 30)))]];
56 let mut buf = Vec::new();
57 write_grid(&mut buf, &grid, true).unwrap();
58 assert_eq!(String::from_utf8(buf).unwrap(), "\x1b[38;2;10;20;30m@\x1b[0m\n");
59 }
60}