From 49e3633c1c935d53368a0fbd1943397682a027a8 Mon Sep 17 00:00:00 2001 From: Owen Brooks Date: Wed, 15 Jun 2022 13:48:46 +1000 Subject: [PATCH] Add alternate Display for concise matrix printing Add format option for concise printing of matrices as semicolon-delimited rows. e.g. println!("{:#}", matrix); --- src/base/matrix.rs | 140 ++++++++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 58 deletions(-) diff --git a/src/base/matrix.rs b/src/base/matrix.rs index fc3ff857..0d0f9f26 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -1893,68 +1893,92 @@ macro_rules! impl_fmt { S: RawStorage, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "std")] - fn val_width(val: &T, f: &mut fmt::Formatter<'_>) -> usize { - match f.precision() { - Some(precision) => format!($fmt_str_with_precision, val, precision) - .chars() - .count(), - None => format!($fmt_str_without_precision, val).chars().count(), - } - } - - #[cfg(not(feature = "std"))] - fn val_width(_: &T, _: &mut fmt::Formatter<'_>) -> usize { - 4 - } - - let (nrows, ncols) = self.shape(); - - if nrows == 0 || ncols == 0 { - return write!(f, "[ ]"); - } - - let mut max_length = 0; - - for i in 0..nrows { - for j in 0..ncols { - max_length = crate::max(max_length, val_width(&self[(i, j)], f)); - } - } - - let max_length_with_space = max_length + 1; - - writeln!(f)?; - writeln!( - f, - " ┌ {:>width$} ┐", - "", - width = max_length_with_space * ncols - 1 - )?; - - for i in 0..nrows { - write!(f, " │")?; - for j in 0..ncols { - let number_length = val_width(&self[(i, j)], f) + 1; - let pad = max_length_with_space - number_length; - write!(f, " {:>thepad$}", "", thepad = pad)?; + if !f.alternate() { // pretty print in 2D layout + #[cfg(feature = "std")] + fn val_width(val: &T, f: &mut fmt::Formatter<'_>) -> usize { match f.precision() { - Some(precision) => { - write!(f, $fmt_str_with_precision, (*self)[(i, j)], precision)? - } - None => write!(f, $fmt_str_without_precision, (*self)[(i, j)])?, + Some(precision) => format!($fmt_str_with_precision, val, precision) + .chars() + .count(), + None => format!($fmt_str_without_precision, val).chars().count(), } } - writeln!(f, " │")?; - } - writeln!( - f, - " └ {:>width$} ┘", - "", - width = max_length_with_space * ncols - 1 - )?; - writeln!(f) + #[cfg(not(feature = "std"))] + fn val_width(_: &T, _: &mut fmt::Formatter<'_>) -> usize { + 4 + } + + let (nrows, ncols) = self.shape(); + + if nrows == 0 || ncols == 0 { + return write!(f, "[ ]"); + } + + let mut max_length = 0; + + for i in 0..nrows { + for j in 0..ncols { + max_length = crate::max(max_length, val_width(&self[(i, j)], f)); + } + } + + let max_length_with_space = max_length + 1; + + writeln!(f)?; // leading newline to ensure no offset from previous prints + writeln!( + f, + " ┌ {:>width$} ┐", + "", + width = max_length_with_space * ncols - 1 + )?; + + for i in 0..nrows { + write!(f, " │")?; + for j in 0..ncols { + let number_length = val_width(&self[(i, j)], f) + 1; + let pad = max_length_with_space - number_length; + write!(f, " {:>thepad$}", "", thepad = pad)?; + match f.precision() { + Some(precision) => { + write!(f, $fmt_str_with_precision, (*self)[(i, j)], precision)? + } + None => write!(f, $fmt_str_without_precision, (*self)[(i, j)])?, + } + } + writeln!(f, " │")?; + } + + write!( + f, + " └ {:>width$} ┘", + "", + width = max_length_with_space * ncols - 1 + ) + } else { // print on single line with semicolon-delimited rows and comma-delimited columns + let (nrows, ncols) = self.shape(); + write!(f, "[")?; + for row in 0..nrows { + for col in 0..ncols { + if col != 0 { + write!(f, ", ")?; + } + match f.precision() { + Some(precision) => write!( + f, + $fmt_str_with_precision, + (*self)[(row, col)], + precision + )?, + None => write!(f, $fmt_str_without_precision, (*self)[(row, col)])?, + } + } + if row != nrows - 1 { + write!(f, "; ")?; + } + } + write!(f, "]") + } } } };