Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

re_format: add general format_int function #5754

Merged
merged 2 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 81 additions & 12 deletions crates/re_format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub mod arrow;

mod time;

use std::{cmp::PartialOrd, fmt::Display};

pub use time::next_grid_tick_magnitude_ns;

// --- Numbers ---
Expand All @@ -16,30 +18,97 @@ pub use time::next_grid_tick_magnitude_ns;
/// Looks slightly different from the normal hyphen `-`.
const MINUS: char = '−';

/// Pretty format an unsigned integer by using thousands separators for readability.
///
/// The returned value is for human eyes only, and can not be parsed
/// by the normal `usize::from_str` function.
pub fn format_uint<Uint>(number: Uint) -> String
where
Uint: Copy + num_traits::Unsigned + std::fmt::Display,
{
add_thousands_separators(&number.to_string())
// TODO(rust-num/num-traits#315): waiting for https://github.com/rust-num/num-traits/issues/315 to land
pub trait UnsignedAbs {
/// An unsigned type which is large enough to hold the absolute value of `Self`.
type Unsigned;

/// Computes the absolute value of `self` without any wrapping or panicking.
fn unsigned_abs(self) -> Self::Unsigned;
}

impl UnsignedAbs for i8 {
type Unsigned = u8;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

impl UnsignedAbs for i16 {
type Unsigned = u16;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

impl UnsignedAbs for i32 {
type Unsigned = u32;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

impl UnsignedAbs for i64 {
type Unsigned = u64;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

impl UnsignedAbs for i128 {
type Unsigned = u128;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

impl UnsignedAbs for isize {
type Unsigned = usize;

#[inline]
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}

/// Pretty format a signed number by using thousands separators for readability.
///
/// The returned value is for human eyes only, and can not be parsed
/// by the normal `usize::from_str` function.
pub fn format_i64(number: i64) -> String {
if number < 0 {
// TODO(rust-num/num-traits#315): generalize this to all signed integers once https://github.com/rust-num/num-traits/issues/315 lands
pub fn format_int<Int>(number: Int) -> String
where
Int: Display + PartialOrd + num_traits::Zero + UnsignedAbs,
Int::Unsigned: Display + num_traits::Unsigned,
{
if number < Int::zero() {
format!("{MINUS}{}", format_uint(number.unsigned_abs()))
} else {
add_thousands_separators(&number.to_string())
}
}

/// Pretty format an unsigned integer by using thousands separators for readability.
///
/// The returned value is for human eyes only, and can not be parsed
/// by the normal `usize::from_str` function.
#[allow(clippy::needless_pass_by_value)]
pub fn format_uint<Uint>(number: Uint) -> String
where
Uint: Display + num_traits::Unsigned,
{
add_thousands_separators(&number.to_string())
}

/// Add thousands separators to a number, every three steps,
/// counting from the last character.
fn add_thousands_separators(number: &str) -> String {
Expand Down
2 changes: 1 addition & 1 deletion crates/re_log_types/src/time_point/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl TimeType {
} else {
match self {
Self::Time => Time::from(time_int).format(time_zone_for_timestamps),
Self::Sequence => format!("#{}", re_format::format_i64(time_int.0)),
Self::Sequence => format!("#{}", re_format::format_int(time_int.0)),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/re_time_panel/src/paint_ticks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn paint_time_range_ticks(
&ui.clip_rect(),
time_range,
next_power_of_10,
|seq| format!("#{}", re_format::format_i64(seq)),
|seq| format!("#{}", re_format::format_int(seq)),
)
}
}
Expand Down
Loading