Alternate Debug Formatting (#20)
* 🧪 `.alternate()` debug formatting * 🔭 width relative spacing * 🔪 precision + width * 💅🔬 pretty int, float, tuple, struct tests * updates from feedback 1. removed width calculation from iterator 2. added disclaimer to default calculations 3. added test for pretty printing empty grids
This commit is contained in:
parent
ef2882ab5f
commit
3c02c36274
1 changed files with 154 additions and 2 deletions
156
src/lib.rs
156
src/lib.rs
|
@ -772,8 +772,45 @@ impl<T: fmt::Debug> fmt::Debug for Grid<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "[");
|
write!(f, "[");
|
||||||
if self.cols > 0 {
|
if self.cols > 0 {
|
||||||
for (i, _) in self.data.iter().enumerate().step_by(self.cols) {
|
if f.alternate() {
|
||||||
write!(f, "{:?}", &self.data[i..(i + self.cols)]);
|
write!(f, "\n");
|
||||||
|
/*
|
||||||
|
WARNING
|
||||||
|
|
||||||
|
Compound types becoming enormous as the entire `fmt::Debug` width is applied to each item individually.
|
||||||
|
For tuples and structs define padding and precision arguments manually to improve readability.
|
||||||
|
*/
|
||||||
|
let width = f.width().unwrap_or(
|
||||||
|
/*
|
||||||
|
Conditionally calculate the longest item by default.
|
||||||
|
*/
|
||||||
|
self.data
|
||||||
|
.iter()
|
||||||
|
.map(|i| format!("{i:?}").len())
|
||||||
|
.max()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
let precision = f.precision().unwrap_or(2);
|
||||||
|
for (i, _) in self.data.iter().enumerate().step_by(self.cols) {
|
||||||
|
let mut row = self.data[i..(i + self.cols)].iter().peekable();
|
||||||
|
write!(f, " [");
|
||||||
|
while let Some(item) = row.next() {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
" {item:width$.precision$?}",
|
||||||
|
width = width,
|
||||||
|
precision = precision
|
||||||
|
);
|
||||||
|
if row.peek().is_some() {
|
||||||
|
write!(f, ",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(f, "]\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i, _) in self.data.iter().enumerate().step_by(self.cols) {
|
||||||
|
write!(f, "{:?}", &self.data[i..(i + self.cols)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "]")
|
||||||
|
@ -1152,6 +1189,121 @@ mod test {
|
||||||
assert_eq!(format!("{:?}", grid), "[[1, 2, 3][4, 5, 6][7, 8, 9]]");
|
assert_eq!(format!("{:?}", grid), "[[1, 2, 3][4, 5, 6][7, 8, 9]]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fmt_pretty_empty() {
|
||||||
|
let grid: Grid<f32> = grid![];
|
||||||
|
assert_eq!(format!("{:#?}", grid), "[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fmt_pretty_int() {
|
||||||
|
let grid: Grid<u8> = grid![
|
||||||
|
[1,2,3]
|
||||||
|
[4,5,6]
|
||||||
|
[7,8,95]
|
||||||
|
];
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ 1, 2, 3]
|
||||||
|
[ 4, 5, 6]
|
||||||
|
[ 7, 8, 95]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#?}", grid), expected_output);
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ 1, 2, 3]
|
||||||
|
[ 4, 5, 6]
|
||||||
|
[ 7, 8, 95]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#3?}", grid), expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fmt_pretty_float() {
|
||||||
|
let grid: Grid<f32> = grid![
|
||||||
|
[1.5,2.6,3.44]
|
||||||
|
[4.775,5.,6.]
|
||||||
|
[7.1,8.23444,95.55]
|
||||||
|
];
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ 1.5, 2.6, 3.4]
|
||||||
|
[ 4.8, 5.0, 6.0]
|
||||||
|
[ 7.1, 8.2, 95.6]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#5.1?}", grid), expected_output);
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ 1.50000, 2.60000, 3.44000]
|
||||||
|
[ 4.77500, 5.00000, 6.00000]
|
||||||
|
[ 7.10000, 8.23444, 95.55000]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#8.5?}", grid), expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fmt_pretty_tuple() {
|
||||||
|
let grid: Grid<(i32, i32)> = grid![
|
||||||
|
[(5,66), (432, 55)]
|
||||||
|
[(80, 90), (5, 6)]
|
||||||
|
];
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ ( 5, 66), ( 432, 55)]
|
||||||
|
[ ( 80, 90), ( 5, 6)]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#?}", grid), expected_output);
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ ( 5, 66), (432, 55)]
|
||||||
|
[ ( 80, 90), ( 5, 6)]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#3?}", grid), expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fmt_pretty_struct_derived() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Person {
|
||||||
|
_name: String,
|
||||||
|
_precise_age: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Person {
|
||||||
|
fn new(name: &str, precise_age: f32) -> Self {
|
||||||
|
Person {
|
||||||
|
_name: name.into(),
|
||||||
|
_precise_age: precise_age,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let grid: Grid<Person> = grid![
|
||||||
|
[Person::new("Vic", 24.5), Person::new("Mr. Very Long Name", 1955.)]
|
||||||
|
[Person::new("Sam", 8.9995), Person::new("John Doe", 40.14)]
|
||||||
|
];
|
||||||
|
|
||||||
|
let expected_output =
|
||||||
|
r#"[
|
||||||
|
[ Person { _name: "Vic", _precise_age: 24.50000 }, Person { _name: "Mr. Very Long Name", _precise_age: 1955.00000 }]
|
||||||
|
[ Person { _name: "Sam", _precise_age: 8.99950 }, Person { _name: "John Doe", _precise_age: 40.14000 }]
|
||||||
|
]"#;
|
||||||
|
|
||||||
|
assert_eq!(format!("{:#5.5?}", grid), expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn clone() {
|
fn clone() {
|
||||||
let grid = grid![[1, 2, 3][4, 5, 6]];
|
let grid = grid![[1, 2, 3][4, 5, 6]];
|
||||||
|
|
Loading…
Reference in a new issue