From 3c02c362748439adcf212e8cb7ddcdd99319a55e Mon Sep 17 00:00:00 2001 From: Isaac Cloos <46393653+IsaacCloos@users.noreply.github.com> Date: Fri, 19 Aug 2022 16:10:20 -0400 Subject: [PATCH] Alternate Debug Formatting (#20) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ๐Ÿงช `.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 --- src/lib.rs | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 365f3e4..c45fa85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -772,8 +772,45 @@ impl fmt::Debug for Grid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "["); if self.cols > 0 { - for (i, _) in self.data.iter().enumerate().step_by(self.cols) { - write!(f, "{:?}", &self.data[i..(i + self.cols)]); + if f.alternate() { + 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, "]") @@ -1152,6 +1189,121 @@ mod test { assert_eq!(format!("{:?}", grid), "[[1, 2, 3][4, 5, 6][7, 8, 9]]"); } + #[test] + fn fmt_pretty_empty() { + let grid: Grid = grid![]; + assert_eq!(format!("{:#?}", grid), "[]"); + } + + #[test] + fn fmt_pretty_int() { + let grid: Grid = 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 = 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 = 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] fn clone() { let grid = grid![[1, 2, 3][4, 5, 6]];