mem_dbg 0.4.3

Traits and associated procedural macros to display recursively the layout and memory usage of a value
Documentation
/*
 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
 * SPDX-FileCopyrightText: 2023 Inria
 *
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
 */

/// Given a size in bytes, returns it in a human-readable format using SI-prefixed units.
///
/// # Examples
///
/// ```rust
/// use mem_dbg::humanize_float;
///
/// let (x, uom) = humanize_float(100);
/// assert_eq!(x, 100.0);
/// assert_eq!(uom, " B");
///
/// let (x, uom) = humanize_float(1234);
/// assert_eq!(x, 1.234);
/// assert_eq!(uom, "kB");
///
/// let (x, uom) = humanize_float(0);
/// assert_eq!(x, 0.0);
/// assert_eq!(uom, " B");
///
/// let (x, uom) = humanize_float(usize::MAX);
/// assert!(x > 1.0);
/// #[cfg(target_pointer_width = "64")]
/// assert_eq!(uom, "EB");
/// #[cfg(target_pointer_width = "32")]
/// assert_eq!(uom, "GB");
/// ```
pub const fn humanize_float(x: usize) -> (f64, &'static str) {
    const UOM: [&str; 7] = [" B", "kB", "MB", "GB", "TB", "PB", "EB"];
    let mut uom_idx = 0;

    if x == 0 {
        return (0.0, UOM[uom_idx]);
    }

    let mut x = x as f64;

    while x >= 1000.0 && uom_idx < UOM.len() - 1 {
        uom_idx += 1;
        x /= 1000.0;
    }

    (x, UOM[uom_idx])
}

/// Returns the color code corresponding to the size.
///
/// # Examples
///
/// ```rust
/// use mem_dbg::color;
/// use mem_dbg::reset_color;
///
/// assert_eq!(color(100), reset_color());
/// assert_eq!(color(1000), "\x1B[32m");
/// assert_eq!(color(1_000_000), "\x1B[33m");
/// assert_eq!(color(1_000_000_000), "\x1B[31m");
/// ```
pub const fn color(x: usize) -> &'static str {
    const KB: usize = 1000;
    const MB: usize = 1_000_000;
    const GB: usize = 1_000_000_000;
    match x {
        // white
        ..KB => reset_color(),
        // green
        KB..MB => "\x1B[32m",
        // yellow
        MB..GB => "\x1B[33m",
        // red
        _ => "\x1B[31m",
    }
}

/// Returns the color used to print types.
///
/// # Examples
///
/// ```rust
/// use mem_dbg::type_color;
///
/// assert_eq!(type_color(), "\x1B[38;2;128;128;128m");
/// ```
pub const fn type_color() -> &'static str {
    // custom grey
    "\x1B[38;2;128;128;128m"
}

/// Returns the color code to reset the color.
///
/// # Examples
///
/// ```rust
/// use mem_dbg::reset_color;
///
/// assert_eq!(reset_color(), "\x1B[0m");
/// ```
pub const fn reset_color() -> &'static str {
    "\x1B[0m"
}

/// Returns the color used to print reference addresses (first encounter).
///
/// # Examples
///
/// ```rust
/// use mem_dbg::ref_color;
///
/// assert_eq!(ref_color(), "\x1B[36m");
/// ```
pub const fn ref_color() -> &'static str {
    // cyan
    "\x1B[36m"
}

/// Returns the color used to print back-reference arrows (subsequent encounters).
///
/// # Examples
///
/// ```rust
/// use mem_dbg::backref_color;
///
/// assert_eq!(backref_color(), "\x1B[35m");
/// ```
pub const fn backref_color() -> &'static str {
    // magenta
    "\x1B[35m"
}

/// Returns the number of digits of a number.
///
/// ```
/// use mem_dbg::n_of_digits;
///
/// assert_eq!(n_of_digits(0), 1);
/// assert_eq!(n_of_digits(1), 1);
/// assert_eq!(n_of_digits(10), 2);
/// assert_eq!(n_of_digits(100), 3);
/// assert_eq!(n_of_digits(1000), 4);
/// assert_eq!(n_of_digits(10000), 5);
/// assert_eq!(n_of_digits(100000), 6);
/// ```
pub const fn n_of_digits(x: usize) -> usize {
    if x == 0 {
        return 1;
    }
    let mut digits = 0;
    let mut x = x;
    while x > 0 {
        digits += 1;
        x /= 10;
    }
    digits
}