mirror of
https://github.com/LeopoldArkham/humansize
synced 2024-11-10 06:14:15 +00:00
fmt
This commit is contained in:
parent
328bde1bdc
commit
d6d5b342b5
9 changed files with 95 additions and 107 deletions
|
@ -7,5 +7,4 @@ fn main() {
|
|||
|
||||
// Then use it
|
||||
println!("{}", format_size(3024usize, custom_options));
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
extern crate humansize;
|
||||
|
||||
use humansize::{format_size, format_size_i, BINARY, WINDOWS, DECIMAL, Formatter, IFormatter};
|
||||
|
||||
use humansize::{format_size, format_size_i, Formatter, IFormatter, BINARY, DECIMAL, WINDOWS};
|
||||
|
||||
fn main() {
|
||||
println!("{}", format_size(5456usize, BINARY));
|
||||
println!("{}", format_size(1024usize, DECIMAL));
|
||||
println!("{}", format_size(1000usize, WINDOWS));
|
||||
|
||||
|
||||
println!("{}", format_size(1_023_654_123_654_u64, BINARY));
|
||||
println!("{}", format_size(123456789usize, DECIMAL));
|
||||
println!("{}", format_size_i(-123456789, WINDOWS));
|
||||
|
||||
println!("{}", Formatter::new(1234u32, BINARY));
|
||||
println!("{}", IFormatter::new(1234, BINARY));
|
||||
|
||||
}
|
||||
|
|
|
@ -5,10 +5,7 @@ use crate::options::FormatSizeOptions;
|
|||
use crate::IFormatter;
|
||||
|
||||
pub fn format_size_i(input: impl ToF64, options: impl AsRef<FormatSizeOptions>) -> String {
|
||||
format!(
|
||||
"{}",
|
||||
IFormatter::new(input, options)
|
||||
)
|
||||
format!("{}", IFormatter::new(input, options))
|
||||
}
|
||||
|
||||
pub fn format_size(input: impl ToF64 + Unsigned, options: impl AsRef<FormatSizeOptions>) -> String {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use libm::{fabs, modf};
|
||||
|
||||
use crate::{ToF64, FormatSizeOptions, Kilo, BaseUnit, Unsigned, scales, utils::f64_eq};
|
||||
use crate::{scales, utils::f64_eq, BaseUnit, FormatSizeOptions, Kilo, ToF64, Unsigned};
|
||||
|
||||
pub struct IFormatter<T: ToF64, O: AsRef<FormatSizeOptions>> {
|
||||
value: T,
|
||||
|
@ -8,88 +8,88 @@ pub struct IFormatter<T: ToF64, O: AsRef<FormatSizeOptions>> {
|
|||
}
|
||||
|
||||
impl<V: ToF64, O: AsRef<FormatSizeOptions>> IFormatter<V, O> {
|
||||
pub fn new(value: V, options: O) -> Self {
|
||||
IFormatter { value, options }
|
||||
}
|
||||
pub fn new(value: V, options: O) -> Self {
|
||||
IFormatter { value, options }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToF64, O: AsRef<FormatSizeOptions>> core::fmt::Display for IFormatter<T, O> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
let opts = self.options.as_ref();
|
||||
let divider = opts.kilo.value();
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
let opts = self.options.as_ref();
|
||||
let divider = opts.kilo.value();
|
||||
|
||||
let mut size: f64 = self.value.to_f64();
|
||||
let mut scale_idx = 0;
|
||||
let mut size: f64 = self.value.to_f64();
|
||||
let mut scale_idx = 0;
|
||||
|
||||
if let Some(val) = opts.fixed_at {
|
||||
while scale_idx != val as usize {
|
||||
size /= divider;
|
||||
scale_idx += 1;
|
||||
}
|
||||
} else {
|
||||
while fabs(size) >= divider {
|
||||
size /= divider;
|
||||
scale_idx += 1;
|
||||
}
|
||||
}
|
||||
if let Some(val) = opts.fixed_at {
|
||||
while scale_idx != val as usize {
|
||||
size /= divider;
|
||||
scale_idx += 1;
|
||||
}
|
||||
} else {
|
||||
while fabs(size) >= divider {
|
||||
size /= divider;
|
||||
scale_idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut scale = match (opts.units, opts.long_units, opts.base_unit) {
|
||||
(Kilo::Decimal, false, BaseUnit::Byte) => scales::SCALE_DECIMAL[scale_idx],
|
||||
(Kilo::Decimal, true, BaseUnit::Byte) => scales::SCALE_DECIMAL_LONG[scale_idx],
|
||||
(Kilo::Binary, false, BaseUnit::Byte) => scales::SCALE_BINARY[scale_idx],
|
||||
(Kilo::Binary, true, BaseUnit::Byte) => scales::SCALE_BINARY_LONG[scale_idx],
|
||||
(Kilo::Decimal, false, BaseUnit::Bit) => scales::SCALE_DECIMAL_BIT[scale_idx],
|
||||
(Kilo::Decimal, true, BaseUnit::Bit) => scales::SCALE_DECIMAL_BIT_LONG[scale_idx],
|
||||
(Kilo::Binary, false, BaseUnit::Bit) => scales::SCALE_BINARY_BIT[scale_idx],
|
||||
(Kilo::Binary, true, BaseUnit::Bit) => scales::SCALE_BINARY_BIT_LONG[scale_idx],
|
||||
};
|
||||
let mut scale = match (opts.units, opts.long_units, opts.base_unit) {
|
||||
(Kilo::Decimal, false, BaseUnit::Byte) => scales::SCALE_DECIMAL[scale_idx],
|
||||
(Kilo::Decimal, true, BaseUnit::Byte) => scales::SCALE_DECIMAL_LONG[scale_idx],
|
||||
(Kilo::Binary, false, BaseUnit::Byte) => scales::SCALE_BINARY[scale_idx],
|
||||
(Kilo::Binary, true, BaseUnit::Byte) => scales::SCALE_BINARY_LONG[scale_idx],
|
||||
(Kilo::Decimal, false, BaseUnit::Bit) => scales::SCALE_DECIMAL_BIT[scale_idx],
|
||||
(Kilo::Decimal, true, BaseUnit::Bit) => scales::SCALE_DECIMAL_BIT_LONG[scale_idx],
|
||||
(Kilo::Binary, false, BaseUnit::Bit) => scales::SCALE_BINARY_BIT[scale_idx],
|
||||
(Kilo::Binary, true, BaseUnit::Bit) => scales::SCALE_BINARY_BIT_LONG[scale_idx],
|
||||
};
|
||||
|
||||
// Remove "s" from the scale if the size is 1.x
|
||||
let (fpart, ipart) = modf(size);
|
||||
if f64_eq(ipart, 1.0)
|
||||
&& (opts.long_units || (opts.base_unit == BaseUnit::Bit && scale_idx == 0))
|
||||
{
|
||||
scale = &scale[0..scale.len() - 1];
|
||||
}
|
||||
// Remove "s" from the scale if the size is 1.x
|
||||
let (fpart, ipart) = modf(size);
|
||||
if f64_eq(ipart, 1.0)
|
||||
&& (opts.long_units || (opts.base_unit == BaseUnit::Bit && scale_idx == 0))
|
||||
{
|
||||
scale = &scale[0..scale.len() - 1];
|
||||
}
|
||||
|
||||
let places = if f64_eq(fpart, 0.0) {
|
||||
opts.decimal_zeroes
|
||||
} else {
|
||||
opts.decimal_places
|
||||
};
|
||||
let places = if f64_eq(fpart, 0.0) {
|
||||
opts.decimal_zeroes
|
||||
} else {
|
||||
opts.decimal_places
|
||||
};
|
||||
|
||||
let space = if opts.space_after_value { " " } else { "" };
|
||||
let space = if opts.space_after_value { " " } else { "" };
|
||||
|
||||
write!(f, "{:.*}{}{}{}", places, size, space, scale, opts.suffix)
|
||||
}
|
||||
write!(f, "{:.*}{}{}{}", places, size, space, scale, opts.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, U: ToF64 + Unsigned + Copy, O: AsRef<FormatSizeOptions>> From<&'a Formatter<U, O>>
|
||||
for IFormatter<U, &'a O>
|
||||
for IFormatter<U, &'a O>
|
||||
{
|
||||
fn from(source: &'a Formatter<U, O>) -> Self {
|
||||
IFormatter {
|
||||
value: source.value,
|
||||
options: &source.options,
|
||||
}
|
||||
}
|
||||
fn from(source: &'a Formatter<U, O>) -> Self {
|
||||
IFormatter {
|
||||
value: source.value,
|
||||
options: &source.options,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Formatter<T: ToF64 + Unsigned, O: AsRef<FormatSizeOptions>> {
|
||||
value: T,
|
||||
options: O,
|
||||
value: T,
|
||||
options: O,
|
||||
}
|
||||
|
||||
impl<V: ToF64 + Unsigned, O: AsRef<FormatSizeOptions>> Formatter<V, O> {
|
||||
pub fn new(value: V, options: O) -> Self {
|
||||
Formatter { value, options }
|
||||
}
|
||||
pub fn new(value: V, options: O) -> Self {
|
||||
Formatter { value, options }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToF64 + Unsigned + Copy, O: AsRef<FormatSizeOptions> + Copy> core::fmt::Display
|
||||
for Formatter<T, O>
|
||||
for Formatter<T, O>
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "{}", IFormatter::from(self))
|
||||
}
|
||||
}
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "{}", IFormatter::from(self))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
use crate::{FormatSizeOptions, Formatter, IFormatter, Signed, ToF64, Unsigned};
|
||||
use alloc::string::String;
|
||||
use crate::{IFormatter, Formatter, FormatSizeOptions, ToF64, Unsigned, Signed};
|
||||
|
||||
pub trait FormatSize<T> {
|
||||
fn format_size(&self, opts: FormatSizeOptions) -> String;
|
||||
|
@ -20,4 +19,4 @@ impl<T: ToF64 + Signed + Copy> FormatSizeI<T> for T {
|
|||
fn format_size_i(&self, opts: FormatSizeOptions) -> String {
|
||||
format!("{}", IFormatter::new(*self, opts))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ humansize = "2.0.0"
|
|||
- `DECIMAL` (SI)
|
||||
- `BINARY` (IEC)
|
||||
- `WINDOWS` (IEC values but SI units)
|
||||
2. Call `format_size` with an unsigned integer
|
||||
2. Call `format_size` with an unsigned integer
|
||||
|
||||
```rust
|
||||
use humansize::{format_size, DECIMAL};
|
||||
|
@ -118,13 +118,13 @@ extern crate alloc;
|
|||
extern crate libm;
|
||||
|
||||
mod options;
|
||||
pub use options::{BaseUnit, FixedAt, FormatSizeOptions, Kilo, BINARY, WINDOWS, DECIMAL};
|
||||
pub use options::{BaseUnit, FixedAt, FormatSizeOptions, Kilo, BINARY, DECIMAL, WINDOWS};
|
||||
|
||||
mod numeric_traits;
|
||||
pub use numeric_traits::{ToF64, Unsigned, Signed};
|
||||
pub use numeric_traits::{Signed, ToF64, Unsigned};
|
||||
|
||||
mod utils;
|
||||
mod scales;
|
||||
mod utils;
|
||||
|
||||
#[cfg(not(feature = "no_alloc"))]
|
||||
mod allocating;
|
||||
|
|
|
@ -24,7 +24,6 @@ macro_rules! impl_unsigned {
|
|||
|
||||
impl_unsigned!(for usize u8 u16 u32 u64);
|
||||
|
||||
|
||||
pub trait Signed {}
|
||||
|
||||
macro_rules! impl_unsigned {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use libm::fabs;
|
||||
|
||||
pub(crate) fn f64_eq(left: f64, right: f64) -> bool {
|
||||
left == right || fabs(left - right) <= f64::EPSILON
|
||||
}
|
||||
left == right || fabs(left - right) <= f64::EPSILON
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use humansize::{
|
||||
format_size, format_size_i, BaseUnit, FixedAt, FormatSizeOptions, BINARY, WINDOWS, DECIMAL,
|
||||
format_size, format_size_i, BaseUnit, FixedAt, FormatSizeOptions, BINARY, DECIMAL, WINDOWS,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -19,41 +19,31 @@ fn test_sizes() {
|
|||
let custom_options = FormatSizeOptions::from(BINARY).suffix("/s");
|
||||
assert_eq!(format_size(999u32, custom_options), "999 B/s");
|
||||
|
||||
let custom_options = FormatSizeOptions::from(DECIMAL).suffix("/day").space_after_value(false);
|
||||
let custom_options = FormatSizeOptions::from(DECIMAL)
|
||||
.suffix("/day")
|
||||
.space_after_value(false);
|
||||
assert_eq!(format_size(1000u32, custom_options), "1kB/day");
|
||||
|
||||
|
||||
let custom_options = FormatSizeOptions::from(BINARY).fixed_at(Some(FixedAt::Base));
|
||||
assert_eq!(format_size(2048u32, custom_options), "2048 B");
|
||||
|
||||
|
||||
let custom_options = FormatSizeOptions::from(BINARY).fixed_at(Some(FixedAt::Base)).long_units(true);
|
||||
let custom_options = FormatSizeOptions::from(BINARY)
|
||||
.fixed_at(Some(FixedAt::Base))
|
||||
.long_units(true);
|
||||
assert_eq!(format_size(2048u32, custom_options), "2048 Bytes");
|
||||
|
||||
|
||||
|
||||
let custom_options = FormatSizeOptions::from(BINARY).fixed_at(Some(FixedAt::Kilo));
|
||||
assert_eq!(
|
||||
format_size(16584975u32, custom_options),
|
||||
"16196.26 KiB"
|
||||
);
|
||||
assert_eq!(
|
||||
format_size_i(-16584975, custom_options),
|
||||
"-16196.26 KiB"
|
||||
);
|
||||
assert_eq!(format_size(16584975u32, custom_options), "16196.26 KiB");
|
||||
assert_eq!(format_size_i(-16584975, custom_options), "-16196.26 KiB");
|
||||
|
||||
|
||||
|
||||
let custom_options = FormatSizeOptions::from(BINARY).fixed_at(Some(FixedAt::Tera)).decimal_places(10);
|
||||
assert_eq!(
|
||||
format_size(15284975u32, custom_options),
|
||||
"0.0000139016 TiB"
|
||||
);
|
||||
let custom_options = FormatSizeOptions::from(BINARY)
|
||||
.fixed_at(Some(FixedAt::Tera))
|
||||
.decimal_places(10);
|
||||
assert_eq!(format_size(15284975u32, custom_options), "0.0000139016 TiB");
|
||||
|
||||
assert_eq!((format_size_i(-5500, DECIMAL)), "-5.50 kB");
|
||||
assert_eq!((format_size(5500u32, DECIMAL)), "5.50 kB");
|
||||
|
||||
|
||||
let custom_options = FormatSizeOptions::from(DECIMAL).base_unit(BaseUnit::Bit);
|
||||
assert_eq!((format_size(1usize, custom_options)), "1 bit");
|
||||
assert_eq!((format_size(150usize, custom_options)), "150 bits");
|
||||
|
@ -71,7 +61,9 @@ fn use_custom_option_struct_twice() {
|
|||
|
||||
#[test]
|
||||
fn pluralization_works() {
|
||||
let options = FormatSizeOptions::from(DECIMAL).long_units(true).decimal_zeroes(2);
|
||||
let options = FormatSizeOptions::from(DECIMAL)
|
||||
.long_units(true)
|
||||
.decimal_zeroes(2);
|
||||
|
||||
assert_eq!(format_size(1u32, &options), "1.00 Byte",);
|
||||
|
||||
|
@ -96,13 +88,17 @@ fn pluralization_works() {
|
|||
|
||||
#[test]
|
||||
fn max_value_decimal() {
|
||||
let options = FormatSizeOptions::from(DECIMAL).decimal_places(7).long_units(true);
|
||||
let options = FormatSizeOptions::from(DECIMAL)
|
||||
.decimal_places(7)
|
||||
.long_units(true);
|
||||
assert_eq!(format_size(core::u64::MAX, &options), "18.4467441 Exabytes",);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_value_binary() {
|
||||
let options = FormatSizeOptions::from(BINARY).decimal_places(7).long_units(true);
|
||||
let options = FormatSizeOptions::from(BINARY)
|
||||
.decimal_places(7)
|
||||
.long_units(true);
|
||||
|
||||
assert_eq!(format_size(core::u64::MAX, &options), "16 Exbibytes",);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue