use crate::arr::{shape_iterator::ShapeIterator, vec::core::ArrVec};
use std::fmt::{Debug, Display};
fn right_pading(value: &String, nchar: usize) -> String {
let mut padding = String::new();
while padding.len() < nchar - value.len() {
padding.push_str(" ")
}
let mut out = value.clone();
out.push_str(&padding);
out
}
impl<T> Display for ArrVec<T>
where
T: Display + Copy + Ord + Default,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let shape_len = self.shape.len();
let max_result = self.buff.iter().max();
let min_result = self.buff.iter().min();
if max_result.is_none() || min_result.is_none() {
return write!(f, "[]");
}
let min_value = min_result.unwrap();
let max_value = max_result.unwrap();
let max_str = max_value.to_string();
let min_str = min_value.to_string();
let there_is_negatives = *min_value < T::default();
let item_len = if there_is_negatives && min_str.len() > max_str.len() {
min_str.len()
} else if there_is_negatives {
max_str.len() + 1
} else {
max_str.len()
};
for index in ShapeIterator::new(&self.shape) {
for dim in 0..shape_len {
if index[dim..shape_len].iter().any(|x| *x != 0_usize) {
continue;
}
for _ in 0..dim {
let res = write!(f, " ");
if res.is_err() {
return res;
}
}
let res = write!(f, "[");
if res.is_err() {
return res;
}
if dim < shape_len - 1 {
let res = write!(f, "\n");
if res.is_err() {
return res;
}
};
}
let item = self[&index];
let res = if there_is_negatives && item >= T::default() {
write!(f, " {}", right_pading(&(item.to_string()), item_len - 1))
} else {
write!(f, "{}", right_pading(&(item.to_string()), item_len))
};
if res.is_err() {
return res;
}
if index[shape_len - 1] != self.shape[shape_len - 1] - 1 {
let res = write!(f, " ");
if res.is_err() {
return res;
}
}
for dim in (0..shape_len).rev() {
let dim_size = self.shape[dim];
if index[dim] != dim_size - 1 {
break;
}
if dim != shape_len - 1 {
let res = write!(f, "\n");
if res.is_err() {
return res;
}
for _ in 0..dim {
let res = write!(f, " ");
if res.is_err() {
return res;
}
}
}
let res = write!(f, "]");
if res.is_err() {
return res;
}
if dim > 0 && (index[dim - 1] != self.shape[dim - 1] - 1) {
let res = write!(f, "\n");
if res.is_err() {
return res;
}
}
}
}
Ok(())
}
}
impl<T> Debug for ArrVec<T>
where
T: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ArrVec")
.field("buff", &self.buff)
.field("shape", &self.shape)
.finish()
}
}