si-scale
Format value with units according to SI (système international d’unités).
Version requirement: rustc 1.50+
[]
= "0.1"
Getting started
This crate parses and formats numbers using the SI Scales: from 1 y (yocto, i.e. 1e-24) to 1 Y (Yotta, i.e. 1e24). It is essentially agnostic of units per-se; you can totally keep representing units with strings or uom, or something else.
Pre-defined helper functions
You can use one of the predefined helper functions to format numbers:
use ;
let actual = format!;
let expected = "13 µs";
assert_eq!;
let actual = format!;
let expected = "13.000 µs";
assert_eq!;
Currently the helper functions are:
| helper fn | mantissa | prefix constraint | base | groupings | example |
|---|---|---|---|---|---|
number_() |
"{}" |
UnitOnly |
B1000 | _ |
1.234567, 16 |
| --- | -- | --- | --- | --- | --- |
seconds() |
"{}" |
UnitAndBelow |
B1000 | none | 1.234567 µs, 16 ms |
seconds3() |
"{:.3}" |
UnitAndBelow |
B1000 | none | 1.235 µs, 16.000 ms |
| --- | -- | --- | --- | --- | --- |
bytes() |
"{}" |
UnitAndAbove |
B1000 | _ |
1.234_567 kB |
bytes_() |
"{}" |
UnitOnly |
B1000 | _ |
1_234_567 B |
bytes1() |
"{:.1}" |
UnitAndAbove |
B1000 | none | 2.3 TB |
| --- | -- | --- | --- | --- | --- |
bibytes() |
"{}" |
UnitAndAbove |
B1024 | _ |
1.234_567 MiB |
bibytes1() |
"{:.1}" |
UnitAndAbove |
B1024 | none | 1.2 GiB |
- The prefix constraint
UnitOnlymeans the provided value won't be scaled: if you provide a value larger than 1000, say 1234, it will be printed as 1234. - Base B1000 means 1k = 1000, the base B1024 means 1k = 1024
- Groupings refer to "thousands groupings"; the provided char will be used (for instance 1234 is displayed as 1_234), if none, the value is displayed 1234.
- The mantissa format string acts only upon the mantissa:
"{}"will display the value with all its digits or no digits if it is round, and"{:.3}"for instance will always display one decimal.
Custom helper functions
To define your own format function, use the
scale_fn!() macro. All pre-defined helper
functions from this crate are defined using this macro.
For instance, let's define a formatting function for bits per sec which prints the mantissa with 2 decimals, and also uses base 1024 (where 1 ki = 1024). Note that although we define the function in a separate module, this is not a requirement.
use bits_per_sec;
You can omit the groupings argument of the macro to not sepearate
thousands.
SI Scales
With base = 1000, 1k = 1000, 1M = 1_000_000, 1m = 0.001, 1µ = 0.000_001, etc.
| min (incl.) | max (excl.) | magnitude | prefix |
|---|---|---|---|
| .. | .. | -24 | Prefix::Yocto |
| .. | .. | -21 | Prefix::Zepto |
| .. | .. | -18 | Prefix::Atto |
| .. | .. | -15 | Prefix::Femto |
| .. | .. | -12 | Prefix::Pico |
| .. | .. | -9 | Prefix::Nano |
| 0.000_001 | 0.001 | -6 | Prefix::Micro |
| 0.001 | 1 | -3 | Prefix::Milli |
| 1 | 1_000 | 0 | Prefix::Unit |
| 1000 | 1_000_000 | 3 | Prefix::Kilo |
| 1_000_000 | 1_000_000_000 | 6 | Prefix::Mega |
| .. | .. | 9 | Prefix::Giga |
| .. | .. | 12 | Prefix::Tera |
| .. | .. | 15 | Prefix::Peta |
| .. | .. | 18 | Prefix::Exa |
| .. | .. | 21 | Prefix::Zetta |
| .. | .. | 24 | Prefix::Yotta |
The base is usually 1000, but can also be 1024 (bibytes).
With base = 1024, 1ki = 1024, 1Mi = 1024 * 1024, etc.
Overview
The central representation is the Value type,
which holds
- the mantissa,
- the SI unit prefix (such as "kilo", "Mega", etc),
- and the base which represents the cases where "1 k" means 1000 (most common) and the cases where "1 k" means 1024 (for kiB, MiB, etc).
This crate provides 2 APIs: a low-level API, and a high-level API for convenience.
For the low-level API, the typical use case is
-
first parse a number into a
Value. For doing this, you have to specify the base, and maybe some constraint on the SI scales. SeeValue::new()andValue::new_with() -
then display the
Valueeither by yourself formatting the mantissa and prefix (implements thefmt::Displaytrait), or using the provided Formatter.
For the high-level API, the typical use cases are
-
parse and display a number using the provided functions such as
bibytes(),bytes()orseconds(), they will choose for each number the most appropriate SI scale. -
In case you want the same control granularity as the low-level API (e.g. constraining the scale in some way, using some base, specific mantissa formatting), then you can build a custom function using the provided macro
scale_fn!(). The existing functions such asbibytes(),bytes(),seconds()are all built using this same macro.
The high-level API
The seconds3() function parses a number into a Value and displays it
using 3 decimals and the appropriate scale for seconds (UnitAndBelow),
so that non-sensical scales such as kilo-seconds can't be output. The
seconds() function does the same but formats the mantissa with the
default "{}", so no decimals are printed for integer mantissa.
use ;
let actual = format!;
let expected = "result is 1234.5678 s";
assert_eq!;
let actual = format!;
let expected = "result is 1.230 µs";
assert_eq!;
The bytes() function parses a number into a Value using base 1000
and displays it using 1 decimal and the appropriate scale for bytes
(UnitAndAbove), so that non-sensical scales such as milli-bytes may not
appear.
use ;
let actual = format!;
let expected = "result is 12.3 MB";
assert_eq!;
let actual = format!;
let expected = "result is 16 B";
assert_eq!;
let actual = format!;
let expected = "result is 0.12 B";
assert_eq!;
The bibytes1() function parses a number into a Value using base 1024
and displays it using 1 decimal and the appropriate scale for bytes
(UnitAndAbove), so that non-sensical scales such as milli-bytes may not
appear.
use ;
let actual = format!;
let expected = "result is 11.8 MiB";
assert_eq!;
-- cargo-sync-readme end -