Skip to content

Commit

Permalink
re_format: add general format_int function (#5754)
Browse files Browse the repository at this point in the history
### What
Mostly as an experiment to see if this makes sense as a `trait` for
`num-traits` (see rust-num/num-traits#315)

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[rerun.io/viewer](https://rerun.io/viewer/pr/5754)
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/5754?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/5754?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/5754)
- [Docs
preview](https://rerun.io/preview/b55246f04976986ca8ffac7b72963eae454e374b/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/b55246f04976986ca8ffac7b72963eae454e374b/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
emilk committed Apr 4, 2024
1 parent e7ed16d commit 15eecd3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 14 deletions.
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

0 comments on commit 15eecd3

Please sign in to comment.