Current section

Files

Jump to
humanise src humanise bytes1024.gleam
Raw

src/humanise/bytes1024.gleam

//// This module contains functions for formatting 1024-multiple amounts of data to `String`s (e.g. `"100.0B"`, `"1.5GiB"`).
////
//// Usage generally looks like this:
//// ```
//// bytes1024.Kibibytes(2048.0) |> bytes1024.humanise |> bytes1024.to_string // "2.0MiB"
////
//// // or, if you don't want to change the unit
//// bytes1024.Kilobytes(2048.0) |> bytes1024.to_string // "2048.0KiB"
//// ```
////
//// *Note: This module is for 1024-multiple units! (kibibyte, megbibyte, etc.)*
//// *If you're looking for 1000-multiple units (kilobyte, megabyte, etc.), look at the `bytes` module instead.*
import gleam/bool
import gleam/float
import humanise/util
const kibibyte = 1024.0
const mebibyte = 1_048_576.0
const gibibyte = 1_073_741_824.0
const tebibyte = 1_099_511_627_776.0
/// The main type for holding data amount information.
///
/// Use its constructors directly to specify a unit for the value you want to format.
pub type Bytes {
Bytes(Float)
Kibibytes(Float)
Mebibytes(Float)
Gibibytes(Float)
Tebibytes(Float)
}
/// Convert a value to bytes.
///
/// Example:
/// ```
/// bytes1024.Kibibytes(1.0) |> bytes1024.as_bytes // 1024.0
/// ```
pub fn as_bytes(this bytes: Bytes) -> Float {
case bytes {
Bytes(n) -> n
Kibibytes(n) -> n *. kibibyte
Mebibytes(n) -> n *. mebibyte
Gibibytes(n) -> n *. gibibyte
Tebibytes(n) -> n *. tebibyte
}
}
/// Convert a value to kibibytes.
///
/// Example:
/// ```
/// bytes1024.Bytes(1024.0) |> bytes1024.as_kibibytes // 1.0
/// ```
pub fn as_kibibytes(this bytes: Bytes) -> Float {
as_bytes(bytes) /. kibibyte
}
/// Convert a value to mebibytes.
///
/// Example:
/// ```
/// bytes1024.Kibibytes(1024.0) |> bytes1024.as_mebibytes // 1.0
/// ```
pub fn as_mebibytes(this bytes: Bytes) -> Float {
as_bytes(bytes) /. mebibyte
}
/// Convert a value to gibibytes.
///
/// Example:
/// ```
/// bytes1024.Mebibytes(1024.0) |> bytes1024.as_gibibytes // 1.0
/// ```
pub fn as_gibibytes(this bytes: Bytes) -> Float {
as_bytes(bytes) /. gibibyte
}
/// Convert a value to tebibytes.
///
/// Example:
/// ```
/// bytes1024.Gibibytes(1024.0) |> bytes1024.as_tebibytes // 1.0
/// ```
pub fn as_tebibytes(this bytes: Bytes) -> Float {
as_bytes(bytes) /. tebibyte
}
/// Convert a value to a more optimal unit, if possible.
///
/// Example:
/// ```
/// bytes1024.Mebibytes(0.5) |> bytes1024.humanise // bytes1024.Kibibytes(512.0)
/// ```
pub fn humanise(this bytes: Bytes) -> Bytes {
let abs = float.absolute_value
let b = as_bytes(bytes)
use <- bool.guard(when: abs(b) <. kibibyte, return: Bytes(b))
use <- bool.guard(when: abs(b) <. mebibyte, return: Kibibytes(b /. kibibyte))
use <- bool.guard(when: abs(b) <. gibibyte, return: Mebibytes(b /. mebibyte))
use <- bool.guard(when: abs(b) <. tebibyte, return: Gibibytes(b /. gibibyte))
Tebibytes(b /. tebibyte)
}
/// Format a value as a `String`, rounded to at most 2 decimal places, followed by a unit suffix.
///
/// Example:
/// ```
/// bytes1024.Gibibytes(30.125) |> bytes1024.to_string // "30.13GiB"
/// ```
pub fn to_string(this bytes: Bytes) -> String {
let #(n, suffix) = case bytes {
Bytes(n) -> #(n, "B")
Kibibytes(n) -> #(n, "KiB")
Mebibytes(n) -> #(n, "MiB")
Gibibytes(n) -> #(n, "GiB")
Tebibytes(n) -> #(n, "TiB")
}
util.format(n, suffix)
}