use std::io::{
BufRead,
Write,
};
use crate::graphics::{ColorManipulation, Pixel};
#[must_use]
pub fn color_text(msg: &str, r: u8, g: u8, b: u8) -> String {
format!("\x1b[38;2;{r};{g};{b}m{msg}\x1b[0m")
}
#[must_use]
pub fn color_background<T: core::fmt::Display, F: core::fmt::Display>(
msg: &T,
r: F,
g: F,
b: F,
) -> String {
format!("\x1b[48;2;{r};{g};{b}m{msg}\x1b[0m")
}
#[must_use]
pub fn color<T: core::fmt::Display>(
msg: &str,
r1: T,
g1: T,
b1: T,
r2: T,
g2: T,
b2: T,
) -> String {
format!("\x1b[38;2;{r1};{g1};{b1}m\x1b[48;2;{r2};{g2};{b2}m{msg}\x1b[0m")
}
#[must_use]
pub fn reset_color() -> String {
"\x1b[0m".to_string()
}
pub fn clear_lines(n: usize) -> std::io::Result<()> {
let mut stdout = std::io::stdout();
for _ in 0..n {
write!(stdout, "\x1B[1A")?;
write!(stdout, "\x1B[2K")?;
}
stdout.flush()?;
Ok(())
}
pub fn input(msg: &str) -> std::io::Result<String> {
let mut input = String::new();
println!("{msg}");
std::io::stdin().read_line(&mut input)?;
input.truncate(input.len() - 1);
Ok(input)
}
#[must_use]
pub fn get_console_content(max_lines: usize) -> Vec<String> {
let stdin = std::io::stdin();
let lines = stdin.lock().lines();
let mut recent_lines = Vec::new();
for line in lines.map_while(Result::ok) {
recent_lines.push(line);
if recent_lines.len() > max_lines {
recent_lines.remove(0);
}
}
recent_lines
}
pub fn print_color(buffer: &[Pixel]) {
for i in buffer {
print!("{}", color_text("#", i.r, i.g, i.b));
}
}
pub fn print_color_v(buffer: &[Pixel], width: usize) {
for i in 0..buffer.len() / 2 {
print!(
"{}",
color(
"▄",
buffer[i].r,
buffer[i].g,
buffer[i].b,
buffer[i + width].r,
buffer[i + width].g,
buffer[i + width].b
)
);
if i % width == width - 1 {
println!();
}
}
}
#[must_use]
pub fn color_data_to_console(
pixels: &[u32],
width: usize,
height: usize,
) -> Vec<String> {
let mut output = Vec::new();
for y in 0..height / 2 {
let mut local = String::new();
for x in 0..width {
let pixel_below = pixels[x + y * width];
let pixel = pixels[x + (y + 1) * width];
local.push_str(&color(
"▄",
pixel.red(),
pixel.green(),
pixel.blue(),
pixel_below.red(),
pixel_below.green(),
pixel_below.blue(),
));
}
output.push(local);
}
if height % 2 == 1 {
let mut local = String::new();
for x in 0..width {
let pixel = pixels[x + (height - 1) * width];
local.push_str(&color(
"▄",
pixel.red(),
pixel.green(),
pixel.blue(),
0,
0,
0,
));
}
output.push(local);
}
output
}