Created
May 22, 2022 19:38
-
-
Save Nejat/9c1fa4fd172dc3bfc786a7a9cf4363cd to your computer and use it in GitHub Desktop.
calculate the max debug/display width of items in an iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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