diff options
Diffstat (limited to 'src/printer.rs')
-rw-r--r-- | src/printer.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/printer.rs b/src/printer.rs new file mode 100644 index 0000000..7091124 --- /dev/null +++ b/src/printer.rs @@ -0,0 +1,117 @@ +pub struct Printer<W: std::io::Write> { + lines: usize, + buffer: String, + writer: W, +} + +impl<W> From<W> for Printer<W> +where + W: std::io::Write, +{ + fn from(value: W) -> Self { + Self { + lines: 0, + buffer: String::new(), + writer: value, + } + } +} + +impl<W: std::io::Write> Printer<W> { + pub fn write(&mut self) -> std::io::Result<&mut Self> { + writeln!(self.writer, "{}", self.buffer)?; + self.writer.flush()?; + + self.lines = self.buffer.lines().count() + 1; + self.buffer.clear(); + + Ok(self) + } + + pub fn write_pause(&mut self, prompt: &str) -> std::io::Result<&mut Self> { + use std::io::Read; + + self.buffer.push('\n'); + self.buffer.push_str(prompt); + + self.write()?; + let _ = std::io::stdin().read(&mut [0u8])?; + Ok(self) + } + + pub fn write_pause_condition( + &mut self, + prompt: &str, + cond: bool, + ) -> std::io::Result<&mut Self> { + if cond { + self.write_pause(prompt) + } else { + self.write() + } + } + + pub fn write_sleep(&mut self, time: u64) -> std::io::Result<&mut Self> { + self.write()?; + std::thread::sleep(std::time::Duration::from_millis(time)); + + Ok(self) + } + + pub fn clear(&mut self) -> &mut Self { + self.buffer + .insert_str(0, &"\x1b[1A\x1b[K".repeat(self.lines)); + self.lines = 0; + self + } + + pub fn with(&mut self, fmt: std::fmt::Arguments) -> &mut Self { + self.buffer.push('\n'); + self.buffer.push_str(format!("{}", fmt).as_str()); + self + } + + pub fn with_grid<T: std::fmt::Display>(&mut self, grid: &[Vec<T>]) -> &mut Self { + let s = grid + .iter() + .flat_map(|row| { + row.iter() + .map(|s| s.to_string()) + .chain(std::iter::once("\n".to_string())) + }) + .collect::<String>(); + + self.buffer.push('\n'); + self.buffer.push_str(s.as_str()); + + self + } + + pub fn with_grid_path<T: std::fmt::Display>( + &mut self, + grid: &[Vec<T>], + highlight: &[(usize, usize)], + ) -> &mut Self { + let s = grid + .iter() + .enumerate() + .flat_map(|(x, row)| { + row.iter() + .enumerate() + .map(move |(y, s)| { + if highlight.contains(&(x, y)) { + format!("\x1b[1;30;42m{s}\x1b[0m") + } else { + s.to_string() + } + }) + .chain(std::iter::once("\n".to_string())) + }) + .collect::<String>(); + + self.buffer.push('\n'); + self.buffer.push_str(s.as_str()); + + self + } +} |