use crate::Smooth;
/// Extension trait to consistently make multiple numbers human-readable.
// module is not public, type is re-exported
#[allow(clippy::module_name_repetitions)]
pub trait MultiSmooth {
/// Rounds all numbers to the specified decimals.
///
/// # Examples
///
/// ```rust
/// # use smooth::MultiSmooth;
/// let mut numbers = [1.1111, 5.5555, 9.9999];
/// numbers.round_to_mut(2);
///
/// assert_eq!(numbers, [1.11, 5.56, 10.0]);
/// ```
fn round_to_mut(&mut self, decimals: u32);
/// Returns formatted, consistently rounded numbers.
///
/// # Examples
///
/// ```rust
/// # use smooth::MultiSmooth;
/// let numbers = [1.1111, 5.5555, 9.9999];
///
/// assert_eq!(numbers.round_to_str(2), ["1.11", "5.56", "10"]);
/// ```
fn round_to_str(&self, decimals: u32) -> Vec<String>;
/// Consistently smoothes all numbers.
///
/// # Examples
///
/// ```rust
/// # use smooth::MultiSmooth;
/// let mut numbers = [1.1111, 5.5555, 9.9999];
/// numbers.smooth_mut();
///
/// assert_eq!(numbers, [1.1, 5.6, 10.0]);
/// ```
fn smooth_mut(&mut self);
/// Returns formatted, consistently smoothed numbers.
///
/// # Examples
///
/// ```rust
/// # use smooth::MultiSmooth;
/// let numbers = [1.1111, 5.5555, 9.9999];
///
/// assert_eq!(numbers.smooth_str(), ["1.1", "5.6", "10"]);
/// ```
fn smooth_str(&self) -> Vec<String>;
#[doc(hidden)]
fn max_td(&self) -> Option<u32>;
}
macro_rules! smooth_impl {
($t:ty) => {
impl MultiSmooth for [$t] {
fn round_to_mut(&mut self, decimals: u32) {
for number in self.iter_mut() {
number.round_to_mut(decimals);
}
}
fn round_to_str(&self, decimals: u32) -> Vec<String> {
self.iter()
.map(|number| format!("{}", number.round_to(decimals)))
.collect()
}
fn smooth_mut(&mut self) {
let max_td = self.max_td();
if let Some(max_td) = max_td {
for number in self.iter_mut() {
let decimals =
2_u32.checked_sub(max_td).unwrap_or_default();
number.round_to_mut(decimals);
}
}
}
fn smooth_str(&self) -> Vec<String> {
let max_td = self.max_td();
if let Some(max_td) = max_td {
self.iter()
.map(|number| {
let decimals =
2_u32.checked_sub(max_td).unwrap_or_default();
format!("{}", number.round_to(decimals))
})
.collect()
} else {
vec![]
}
}
#[doc(hidden)]
fn max_td(&self) -> Option<u32> {
self.iter().map(|number| number.trunc_digits()).max()
}
}
};
}
smooth_impl!(f32);
smooth_impl!(f64);