use super::{super::utils::*, constants::*};
use std::{cmp::*, io::*};
type XY = (usize, usize);
pub trait KittyPlaceholderWriter {
fn write_placeholder_cell(
&mut self,
id: usize,
column: usize,
row: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()>;
fn write_placeholder_row(
&mut self,
id: usize,
start_column: usize,
row: usize,
columns: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()>;
fn write_placeholder_block(
&mut self,
id: usize,
start_column: usize,
start_row: usize,
columns: usize,
rows: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()>;
}
impl<WriteT> KittyPlaceholderWriter for WriteT
where
WriteT: Write,
{
fn write_placeholder_cell(
&mut self,
id: usize,
column: usize,
row: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()> {
let writer = &mut PositionalWriter::new_save_at_maybe(self, position)?;
write_start(writer, id, background_color)?;
write_placeholder(writer, column, row)?;
write_end(writer, background_color.is_some())
}
fn write_placeholder_row(
&mut self,
id: usize,
start_column: usize,
row: usize,
columns: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()> {
let writer = &mut PositionalWriter::new_save_at_maybe(self, position)?;
write_start(writer, id, background_color)?;
for column in start_column..columns {
write_placeholder(writer, column, row)?;
}
write_end(writer, background_color.is_some())
}
fn write_placeholder_block(
&mut self,
id: usize,
start_column: usize,
start_row: usize,
columns: usize,
rows: usize,
position: Option<XY>,
background_color: Option<usize>,
) -> Result<()> {
let writer = &mut PositionalWriter::new_save_at_maybe(self, position)?;
for row in start_row..rows {
if let Some((x, y)) = position {
writer.at(x as u16, (y + row) as u16)?;
}
write_start(writer, id, background_color)?;
for column in start_column..columns {
write_placeholder(writer, column, row)?;
}
write_end(writer, background_color.is_some())?;
if position.is_none() {
write!(writer, "\n")?;
}
}
Ok(())
}
}
const VT100_SET_FOREGROUND_START: &[u8] = b"\x1b[38;5;";
const VT100_SET_BACKGROUND_START: &[u8] = b"\x1b[48;5;";
const VT100_END: &[u8] = b"m";
const VT100_RESET_FOREGROUND: &[u8] = b"\x1b[39m";
const VT100_RESET_BACKGROUND: &[u8] = b"\x1b[49m";
fn write_start<WriteT>(writer: &mut WriteT, id: usize, background_color: Option<usize>) -> Result<()>
where
WriteT: Write,
{
writer.write_all(VT100_SET_FOREGROUND_START)?;
write!(writer, "{}", id)?;
writer.write_all(VT100_END)?;
if let Some(background_color) = background_color {
writer.write_all(VT100_SET_BACKGROUND_START)?;
write!(writer, "{}", background_color)?;
writer.write_all(VT100_END)?;
}
Ok(())
}
fn write_end<WriteT>(writer: &mut WriteT, with_background_color: bool) -> Result<()>
where
WriteT: Write,
{
writer.write_all(VT100_RESET_FOREGROUND)?;
if with_background_color {
writer.write_all(VT100_RESET_BACKGROUND)?;
}
Ok(())
}
fn write_placeholder<WriteT>(writer: &mut WriteT, mut column: usize, mut row: usize) -> Result<()>
where
WriteT: Write,
{
column = min(column, PLACEHOLDER_DIACRITICS_LAST_INDEX);
row = min(row, PLACEHOLDER_DIACRITICS_LAST_INDEX);
write!(writer, "{}", PLACEHOLDER)?;
write!(writer, "{}", PLACEHOLDER_DIACRITICS[row])?;
write!(writer, "{}", PLACEHOLDER_DIACRITICS[column])
}