#![warn(clippy::pedantic)]
#![warn(missing_docs)]
use std::io::{stdout, Write};
#[cfg(feature = "crossterm")]
pub use crossterm;
pub mod clear;
pub mod color;
pub mod goto;
pub mod guard;
pub mod prelude;
pub mod rect;
pub mod style;
pub mod term;
mod line;
mod println;
#[cfg(feature = "crossterm")]
pub mod read;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NonOrthogonal;
fn escape<T: std::fmt::Display>(code: T) {
print!("{}[{}", 27 as char, code);
}
pub fn normal() {
escape("0m");
}
pub fn pixel(c: char, x: u32, y: u32) {
escape(format!("{};{}H{}", y + 1, x + 1, c));
}
pub fn orth_line(c: char, x1: u32, y1: u32, x2: u32, y2: u32) -> Result<(), NonOrthogonal> {
if x1 != x2 && y1 != y2 {
return Err(NonOrthogonal);
}
if x1 == x2 {
let mut y = y1.min(y2);
while y != y1.max(y2) + 1 {
pixel(c, x1, y);
y += 1;
}
} else {
let mut x = x1.min(x2);
while x != x1.max(x2) + 1 {
pixel(c, x, y1);
x += 1;
}
}
Ok(())
}
#[allow(clippy::missing_panics_doc)]
pub fn line(c: char, x1: u32, y1: u32, x2: u32, y2: u32) {
if x1 == x2 || y1 == y2 {
orth_line(c, x1, x2, y1, y2).unwrap();
return;
}
for (x, y) in line::Iter::new(x1, y1, x2, y2) {
pixel(c, x, y);
}
}
pub fn blit<S: AsRef<str>>(src: S, mut x: u32, mut y: u32) {
let src = src.as_ref();
let rows = src.split('\n').map(|s| s.chars());
let ox = x;
for row in rows {
for c in row {
pixel(c, x, y);
x += 1;
}
x = ox;
y += 1;
}
}
pub fn blit_transparent<S: AsRef<str>>(src: S, blank: char, mut x: u32, mut y: u32) {
let src = src.as_ref();
let rows = src.split('\n').map(|s| s.chars());
let ox = x;
for row in rows {
for c in row {
match c {
' ' => goto::right(1),
ch if ch == blank => pixel(' ', x, y),
_ => pixel(c, x, y),
}
x += 1;
}
x = ox;
y += 1;
}
}
pub fn triangle(c: char, x1: u32, y1: u32, x2: u32, y2: u32, x3: u32, y3: u32) {
line(c, x1, y1, x2, y2);
line(c, x2, y2, x3, y3);
line(c, x1, y1, x3, y3);
}
pub fn text<S: AsRef<str>>(s: S, x: u32, mut y: u32) {
let chars = s.as_ref().chars();
let mut nx = x;
for ch in chars {
if ch == '\n' {
nx = x;
y += 1;
}
pixel(ch, nx, y);
nx += 1;
}
}
pub fn flush() {
stdout().flush().expect("Failed to flush stdout");
}