use std::io::Result;
use colored::{ColoredString, Colorize};
use ratatui::backend::TestBackend;
use ratatui::buffer::{Buffer, Cell};
use ratatui::style::{Color, Modifier};
use ratatui::{Frame, Terminal};
fn print_buffer_to_stdout(buffer: &Buffer, cols: usize) {
let contents = &buffer.content;
let mut i: usize = 0;
fn group_cells_by_color(cells: &[Cell]) -> Vec<Vec<Cell>> {
let mut groups: Vec<Vec<Cell>> = Vec::new();
let mut current_run: Vec<Cell> = Vec::new();
for cell in cells {
if current_run.is_empty() || (current_run[0].style() == cell.style()) {
current_run.push(cell.clone());
continue;
}
groups.push(current_run);
current_run = vec![cell.clone()];
}
if !current_run.is_empty() {
groups.push(current_run);
}
groups
}
fn colorize(string: &str, color: Color, modifer: Modifier) -> ColoredString {
let string = match color {
Color::Reset | Color::White => Colorize::normal(string),
Color::Red => Colorize::red(string),
Color::Blue => Colorize::blue(string),
Color::Cyan => Colorize::cyan(string),
Color::Green => Colorize::green(string),
Color::Yellow => Colorize::yellow(string),
Color::Magenta => Colorize::magenta(string),
_ => unimplemented!(),
};
if modifer.is_empty() {
return string;
}
match modifer {
Modifier::DIM => Colorize::dimmed(string),
_ => unimplemented!(),
}
}
while i < contents.len() {
let line = group_cells_by_color(&contents[i..(i + cols)])
.iter()
.map(|cells| {
colorize(
&cells.iter().map(|cell| cell.symbol()).collect::<String>(),
cells[0].fg,
cells[0].modifier,
)
.to_string()
})
.collect::<String>();
println!("{}", line);
i += cols;
}
}
pub fn print_ratatui_frame_to_stdout<F>(cols: usize, rows: usize, callback: F) -> Result<()>
where
F: FnOnce(&mut Frame),
{
let mut terminal = Terminal::new(TestBackend::new(cols as u16, rows as u16))?;
terminal.draw(callback)?;
let buffer = terminal.backend().buffer();
print_buffer_to_stdout(buffer, cols);
Ok(())
}