macro_rules! ansi_esc {
() => {
'\u{1b}'
};
}
macro_rules! ansi_color {
($color_number:expr) => {
concat!(ansi_esc!(), '[', $color_number, 'm')
};
}
macro_rules! ansi_color_reset {
() => {
ansi_color!(0)
};
}
macro_rules! mk_color {
($color_number:expr, $str:expr) => {
concat!(ansi_color!($color_number), $str, ansi_color_reset!())
};
}
macro_rules! red {
($str:expr) => {
mk_color!(31, $str)
};
}
macro_rules! yellow {
($str:expr) => {
mk_color!(33, $str)
};
}
macro_rules! cyan {
($str:expr) => {
mk_color!(36, $str)
};
}
use std::fmt::{self, Display};
use crate::{Cell, Grid};
#[derive(Copy, Clone, Debug)]
pub struct AnsiGridDiff<'a>(pub &'a Grid, pub &'a Grid);
impl Display for AnsiGridDiff<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ref_size = self.0.size();
if ref_size != self.1.size() {
return write!(f, "{}", self.1);
}
let ref_rows = self.0.as_slice().chunks(ref_size);
let rows = self.1.as_slice().chunks(ref_size);
for (ref_row, row) in ref_rows.zip(rows) {
for (ref_cell, cell) in ref_row.iter().zip(row) {
#[rustfmt::skip]
let s = match cell {
Cell::Zero => {
if ref_cell == cell { "0" }
else if ref_cell.is_empty() { cyan!('0') }
else { red!('0') }
},
Cell::One => {
if ref_cell == cell { "1" }
else if ref_cell.is_empty() { yellow!('1') }
else { red!('1') }
},
Cell::Empty => {
if ref_cell == cell { "." }
else { red!('.') }
}
};
f.write_str(s)?;
}
writeln!(f)?;
}
Ok(())
}
}