#![allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss
)]
use std::fmt;
pub(crate) const F64_SAFE_INT_BOUND: f64 = 9_007_199_254_740_992.0;
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct CellMetric(pub f64);
impl fmt::Display for CellMetric {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.0.is_finite() {
return Ok(());
}
if is_safe_integer(self.0) {
write!(f, "{}", self.0 as i64)
} else {
fmt::Display::fmt(&self.0, f)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct MessageMetric(pub f64);
impl fmt::Display for MessageMetric {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.0.is_finite() {
return fmt::Display::fmt(&self.0, f);
}
if is_safe_integer(self.0) {
return write!(f, "{}", self.0 as i64);
}
let formatted = format!("{:.6}", self.0);
let trimmed = formatted.trim_end_matches('0').trim_end_matches('.');
f.write_str(trimmed)
}
}
#[inline]
fn is_safe_integer(v: f64) -> bool {
debug_assert!(v.is_finite());
v.fract() == 0.0 && v.abs() < F64_SAFE_INT_BOUND
}
#[cfg(test)]
#[allow(
clippy::float_cmp,
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::similar_names,
clippy::doc_markdown,
clippy::needless_raw_string_hashes,
clippy::too_many_lines
)]
mod tests {
use super::*;
fn cell(v: f64) -> String {
CellMetric(v).to_string()
}
fn msg(v: f64) -> String {
MessageMetric(v).to_string()
}
#[test]
fn cell_renders_safe_integer_without_trailing_decimal() {
assert_eq!(cell(17.0), "17");
assert_eq!(cell(0.0), "0");
assert_eq!(cell(-1.0), "-1");
}
#[test]
fn cell_renders_non_integer_with_full_precision() {
assert_eq!(cell(12.5), "12.5");
assert_eq!(cell(0.5), "0.5");
let many = cell(0.123_456_789_012_345_67);
assert!(many.starts_with("0.12345678901234"));
assert!(many.len() > 16);
}
#[test]
fn cell_renders_non_finite_as_empty() {
assert_eq!(cell(f64::NAN), "");
assert_eq!(cell(f64::INFINITY), "");
assert_eq!(cell(f64::NEG_INFINITY), "");
}
#[test]
fn cell_at_safe_int_bound_falls_back_to_default_display() {
assert_eq!(cell(F64_SAFE_INT_BOUND), "9007199254740992");
}
#[test]
fn cell_above_safe_int_bound_does_not_saturate_via_as_i64() {
let s = cell(f64::MAX);
assert!(
!s.contains("9223372036854775807"),
"saturating `as i64` cast leaked into output: {s}"
);
assert!(
s.starts_with("179769313486231"),
"expected the leading digits of f64::MAX, got: {s}"
);
}
#[test]
fn message_renders_safe_integer_without_trailing_decimal() {
assert_eq!(msg(17.0), "17");
assert_eq!(msg(15.0), "15");
assert_eq!(msg(-1.0), "-1");
}
#[test]
fn message_renders_non_integer_rounded_to_six_decimals() {
assert_eq!(msg(12.5), "12.5");
assert_eq!(msg(0.123_456_789), "0.123457");
assert_eq!(msg(1.500_000_5), "1.500001");
assert_eq!(msg(1.250_000), "1.25");
}
#[test]
fn message_renders_non_finite_via_default_display() {
assert_eq!(msg(f64::NAN), "NaN");
assert_eq!(msg(f64::INFINITY), "inf");
assert_eq!(msg(f64::NEG_INFINITY), "-inf");
}
#[test]
fn message_writes_into_formatter_without_intermediate_alloc_on_integer_path() {
use std::fmt::Write as _;
let mut buf = String::new();
write!(
buf,
"limit {} value {}",
MessageMetric(15.0),
MessageMetric(17.0)
)
.unwrap();
assert_eq!(buf, "limit 15 value 17");
}
}