Open emilk opened 8 months ago
I think it will have to be a separate trait, especially because it needs an associated type for the unsigned return.
I fear that associated type will also make this a bear to actually use in generic code though. Have you experimented with a local trait doing this?
You are right that a separate trait
makes most sense.
I tried this in a real world example, and it works great:
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 i64 {
type Unsigned = u64;
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}
impl UnsignedAbs for isize {
type Unsigned = usize;
fn unsigned_abs(self) -> Self::Unsigned {
self.unsigned_abs()
}
}
/// Pretty format a signed number by using thousands separators for readability.
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!("-{}", format_uint(number.unsigned_abs()))
} else {
add_thousands_separators(&number.to_string())
}
}
/// Pretty format an unsigned integer by using thousands separators for readability
#[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 {
…
}
I think it should probably take &self
for consistency, especially compared to Signed::abs
.
All signed rust integer types has an
unsgined_abs
function, e.g.(-7_i32).unsigned_abs() == 7_u32
, which is there to correctly handlei32::MIN
(which cannot be negated as ai32
).I suggest we ~either add this to
PrimInt
(returning identify for unsigned integers), or~ add a newUnsignedAbs
trait for this.I'd be happy to make a PR if this sounds good.