Skip to content

Instantly share code, notes, and snippets.

@Nejat
Created May 22, 2022 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nejat/9c1fa4fd172dc3bfc786a7a9cf4363cd to your computer and use it in GitHub Desktop.
Save Nejat/9c1fa4fd172dc3bfc786a7a9cf4363cd to your computer and use it in GitHub Desktop.
calculate the max debug/display width of items in an iterator
use std::fmt::{Debug, Display, Write};
use std::ops::Deref;
/// The output width from a write statement
#[derive(Default, Eq, PartialEq, Ord, PartialOrd)]
struct Width(usize);
impl Width {
/// reset the stored width
fn reset(&mut self) {
self.0 = 0;
}
}
impl Deref for Width {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// Capture the width of a write statement
impl Write for Width {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
self.0 += s.len();
Ok(())
}
}
/// Calculated the maximum debug print width of items in an Iterator
#[inline]
pub fn max_debug_width<T: Debug>(source: impl Iterator<Item=T>) -> usize {
let mut width = Width::default();
// unwrap ok, width write always returns ok
source.map(|v| {
width.reset();
write!(width, "{:?}", v).unwrap();
*width
}).max().unwrap_or_default()
}
/// Calculated the maximum display print width of items in an Iterator
#[inline]
pub fn max_display_width<T: Display>(source: impl Iterator<Item=T>) -> usize {
let mut width = Width::default();
// unwrap ok, width write always returns ok
source.map(|v| {
width.reset();
write!(width, "{}", v).unwrap();
*width
}).max().unwrap_or_default()
}
#[cfg(test)]
mod tests {
use crate::utils::width::{max_debug_width, max_display_width};
#[test]
fn given_a_collection_of_one_value_you_should_be_able_to_calc_max_debug_width() {
let values = vec!["EF"];
let acutal = max_debug_width(values.iter());
let expected = 4;
assert_eq!(expected, acutal);
}
#[test]
fn given_a_collection_of_one_value_you_should_be_able_to_calc_max_display_width() {
let values = vec!["EF"];
let acutal = max_display_width(values.iter());
let expected = 2;
assert_eq!(expected, acutal);
}
#[test]
fn given_a_collection_of_values_you_should_be_able_to_calc_max_debug_width() {
let values = vec!["A", "BCD", "EF", "G", "HIJ", "KL"];
let acutal = max_debug_width(values.iter());
let expected = 5;
assert_eq!(expected, acutal);
}
#[test]
fn given_a_collection_of_values_you_should_be_able_to_calc_max_display_width() {
let values = vec!["A", "BCD", "EF", "G", "HIJ", "KL"];
let acutal = max_display_width(values.iter());
let expected = 3;
assert_eq!(expected, acutal);
}
#[test]
fn given_an_empty_collection_of_values_you_should_be_able_to_calc_max_debug_width() {
let values = <Vec<&str>>::new();
let acutal = max_debug_width(values.iter());
let expected = 0;
assert_eq!(expected, acutal);
}
#[test]
fn given_an_empty_collection_of_values_you_should_be_able_to_calc_max_display_width() {
let values = <Vec<&str>>::new();
let acutal = max_display_width(values.iter());
let expected = 0;
assert_eq!(expected, acutal);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment