Crate human_units

Crate human_units 

Source
Expand description

§human-units

Crates.io Version Docs dependency status

Size, duration and other SI units serialization and formatting library designed for configuration files and command line arguments.

§Introduction

human-units is a library with Size, Duration and other SI-related types specifically designed to be used in configuration files and as command line arguments. These types serialize sizes and durations in exact but human-readable form.

The library also provides FormatSize, FormatDuration traits to print approximate values in a short human-readable form.

  • No floating point operations.
  • No dependencies by default.
  • Supports serde.
  • Supports clap.
  • Supports no_std.
  • Tested with Miri.
  • 72–85% faster than similar libraries (see benchmarks below).
  • 50–87% less binary size compared to similar libraries (see benchmarks below).

§Examples

§Exact human-readable size/duration

use human_units::{Duration, Size};
assert_eq!("1k", Size(1024).to_string());
assert_eq!("1025", Size(1025).to_string());
assert_eq!("1m", Duration(core::time::Duration::from_secs(60)).to_string());
assert_eq!("61s", Duration(core::time::Duration::from_secs(61)).to_string());

§Inexact short human-readable size/duration

use core::time::Duration;
use human_units::{FormatDuration, FormatSize};
assert_eq!("1 KiB", 1024_u64.format_size().to_string());
assert_eq!("1 m", Duration::from_secs(60).format_duration().to_string());

§Custom output

use colored::Colorize;
use core::time::Duration;
use human_units::{FormatDuration, FormattedDuration};

/// Prints the unit in cyan.
struct ColoredDuration(FormattedDuration);

impl core::fmt::Display for ColoredDuration {
    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
        write!(f, "{}", self.0.integer)?;
        if self.0.fraction != 0 {
            write!(f, ".{}", self.0.fraction)?;
        }
        write!(f, " {}", self.0.unit.cyan())
    }
}

// prints "1 m ago", "m" is printed with cyan color
println!("{} ago", ColoredDuration(Duration::from_secs(60).format_duration()));

§Serde integration

use human_units::Size;
use serde::Serialize;

#[derive(Serialize, PartialEq, Eq, Debug)]
struct SizeWrapper {
    size: Size,
}

let object = SizeWrapper{ size: Size(1024) };
assert_eq!(r#"size = "1k""#, toml::to_string(&object).unwrap().trim());

§Clap integration

use clap::Parser;
use human_units::{Duration, Size};

#[derive(Parser, Debug)]
struct Args {
    #[arg(long, value_parser=clap::value_parser!(Duration))]
    timeout: Duration,
    #[arg(long, value_parser=clap::value_parser!(Size))]
    size: Size,
}

let args = Args::parse_from(["test-clap", "--timeout", "1m", "--size", "1g"]);
assert_eq!(args.timeout, Duration(core::time::Duration::from_secs(60)));
assert_eq!(args.size, Size(1024_u64.pow(3)));

§SI units

use human_units::si::{Frequency, Prefix};

// Convert from hertz, internal representation is nHz (nanohertz).
let cpu_freq = Frequency::with_si_prefix(2200, Prefix::Mega);
assert_eq!("2200 MHz", cpu_freq.to_string());
assert_eq!("2.2 GHz", cpu_freq.format_si().to_string());

§IEC units

use human_units::iec::{Byte, Prefix};

let size = Byte::with_iec_prefix(1536, Prefix::Kibi);
assert_eq!("1536 KiB", size.to_string());
assert_eq!("1.5 MiB", size.format_iec().to_string());

§Custom units

use human_units::si::si_unit;
use human_units::iec::iec_unit;

#[si_unit(symbol = "l")]
struct Volume(pub u64);

let volume = Volume(2_200_000_000);
assert_eq!("2200 ml", volume.to_string());

#[iec_unit(symbol = "B/s")]
struct Throughput(pub u64);

let throughput = Throughput(100 * 1024);
assert_eq!("100 KiB/s", throughput.to_string());

§Performance benchmarks

Benchmarks were done with Rust 1.80.1 on a x86_64 laptop.

§Format size

LibraryVersionFeaturesBenchmarkTime
human_bytes0.4.3fastformat_size_then_to_string88.40 ns ± 5.02 ns
human-repr1.1.01024,spaceformat_size_then_to_string161.38 ns ± 13.29 ns
human-units0.1.3format_size_then_to_string24.24 ns ± 1.23 ns

§Format duration

LibraryVersionFeaturesBenchmarkTime
human-repr1.1.01024,spaceformat_duration_then_to_string229.47 ns ± 11.90 ns
human-units0.1.3format_duration_then_to_string41.55 ns ± 2.77 ns

§Executable size benchmarks

Benchmarks were done with Rust 1.80.1 on a x86_64 laptop.

§Format size

LibraryVersionFeaturesBenchmarkExecutable size, B
human_bytes0.4.3fastprint formatted size8192
human-repr1.1.01024,spaceprint formatted size28672
human-units0.1.3print formatted size4096

§Format duration

LibraryVersionFeaturesBenchmarkExecutable size, B
human-repr1.1.01024,spaceprint formatted duration28672
human-units0.1.3print formatted duration4096

Modules§

iec
IEC (International Electrotechnical Commission) units.
si
SI (Système international) units.

Structs§

Buffer
Duration
Exact duration.
DurationError
Duration parsing error.
Error
Unit parsing error.
FormattedDuration
Approximate duration that includes unit, integral and fractional parts as fields.
FormattedSize
Approximate size that includes unit, integral and fractional parts as fields.
Size
Exact size in bytes.
SizeError
Size parsing error.

Traits§

FormatDuration
This trait adds format_duration method to standard Duration type.
FormatSize
This trait adds format_size method to primitive u64 and usize types.