use std::fmt;
use crate::State;
pub enum Item {
Fill(FillItem),
Fn(Box<dyn Fn(&State) -> String + Send + Sync>),
Literal(String),
}
pub enum FillItem {
Bar,
Message,
}
pub struct FormatFloat {
value: f64,
ignore_precision: bool,
}
impl FormatFloat {
pub fn new(value: f64, ignore_precision: bool) -> Self {
assert!(value >= 0.0);
Self {
value,
ignore_precision,
}
}
}
impl fmt::Display for FormatFloat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
if self.ignore_precision {
f.pad_integral(true, "", &format!("{:.0}", self.value))
} else {
let scale = if self.value < 10.0 {
0
} else {
self.value.log10().floor() as usize
};
let fit_width = f.precision().unwrap_or(4);
let precision = fit_width.saturating_sub(scale + 2);
f.pad_integral(true, "", &format!("{:.*}", precision, self.value))
}
} else {
self.value.fmt(f)
}
}
}
pub struct FormatInteger<'a> {
value: u64,
thousands_separator: &'a str,
}
impl<'a> FormatInteger<'a> {
pub fn new(value: u64, thousands_separator: &'a str) -> Self {
Self {
value,
thousands_separator,
}
}
}
impl<'a> fmt::Display for FormatInteger<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
f.pad_integral(
true,
"",
&crate::group_digits(self.value, self.thousands_separator),
)
} else {
self.value.fmt(f)
}
}
}
pub struct FormatPrefix(&'static str);
impl FormatPrefix {
pub fn new(value: &'static str) -> Self {
Self(value)
}
}
impl fmt::Display for FormatPrefix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
if self.0.is_empty() {
Ok(())
} else {
write!(f, " {}", self.0)
}
} else {
self.0.fmt(f)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_float() {
assert_eq!(format!("{:#.4}", FormatFloat::new(1.23456, false)), "1.23");
assert_eq!(format!("{:#.4}", FormatFloat::new(12.3456, false)), "12.3");
assert_eq!(format!("{:#.4}", FormatFloat::new(123.456, false)), "123");
assert_eq!(format!("{:#.4}", FormatFloat::new(1234.56, false)), "1235");
assert_eq!(format!("{:#.4}", FormatFloat::new(12345.6, false)), "12346");
}
#[test]
fn format_float_0() {
assert_eq!(format!("{:#.4}", FormatFloat::new(0.0, false)), "0.00");
}
#[test]
fn format_float_ignore_precision() {
assert_eq!(format!("{:#.4}", FormatFloat::new(12.34, true)), "12");
}
}