Skip to main content

app_memory_usage_fetcher/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2
3#![doc = include_str!("../readme.md")]
4#![deny(clippy::all)]
5#![deny(clippy::cargo)]
6#![deny(clippy::pedantic)]
7#![allow(clippy::doc_markdown)] // Clippy has issues with some names in the OS list
8#![deny(missing_docs)]
9
10use std::num::NonZeroU64;
11
12extern "C" {
13    fn getMemoryUsage() -> i64;
14}
15
16const KILOBYTE: f64 = 1024.0f64;
17const MEGABYTE: f64 = 1024.0f64 * 1024.0f64;
18const GIGABYTE: f64 = 1024.0f64 * 1024.0f64 * 1024.0f64;
19const TERABYTE: f64 = 1024.0f64 * 1024.0f64 * 1024.0f64 * 1024.0f64;
20
21/// Application memory usage in bytes
22///
23/// Returns `None` if the operating system is not supported.
24///
25/// ```
26///  if let Some(bytes) = app_memory_usage_fetcher::get_memory_usage_bytes() {
27///      println!("Memory usage: {} bytes", bytes.get());
28///  }
29/// ```
30#[inline]
31#[must_use]
32pub fn get_memory_usage_bytes() -> Option<NonZeroU64> {
33    let bytes = unsafe { getMemoryUsage() };
34    if bytes <= 0 {
35        None
36    } else {
37        NonZeroU64::new(bytes.cast_unsigned())
38    }
39}
40
41/// Application memory usage in kilobytes (KiB)
42///
43/// ```
44/// if let Some(kb) = app_memory_usage_fetcher::get_memory_usage_kbytes() {
45///     println!("Memory usage: {} KB", kb);
46/// }
47/// ```
48#[inline]
49#[must_use]
50pub fn get_memory_usage_kbytes() -> Option<f64> {
51    #[allow(clippy::cast_precision_loss)]
52    get_memory_usage_bytes().map(|m| m.get() as f64 / KILOBYTE)
53}
54
55/// Application memory usage in megabytes (MiB)
56///
57/// ```
58/// if let Some(mb) = app_memory_usage_fetcher::get_memory_usage_mbytes() {
59///     println!("Memory usage: {} MB", mb);
60/// }
61/// ```
62#[inline]
63#[must_use]
64pub fn get_memory_usage_mbytes() -> Option<f64> {
65    #[allow(clippy::cast_precision_loss)]
66    get_memory_usage_bytes().map(|m| m.get() as f64 / MEGABYTE)
67}
68
69/// Application memory usage in gigabytes (GiB)
70///
71/// ```
72/// if let Some(gb) = app_memory_usage_fetcher::get_memory_usage_gbytes() {
73///     println!("Memory usage: {} GB", gb);
74/// }
75/// ```
76#[inline]
77#[must_use]
78pub fn get_memory_usage_gbytes() -> Option<f64> {
79    #[allow(clippy::cast_precision_loss)]
80    get_memory_usage_bytes().map(|m| m.get() as f64 / GIGABYTE)
81}
82
83/// Application memory usage in terabytes (TiB)
84///
85/// ```
86/// if let Some(tb) = app_memory_usage_fetcher::get_memory_usage_tbytes() {
87///     println!("Memory usage: {} TB", tb);
88/// }
89/// ```
90#[inline]
91#[must_use]
92pub fn get_memory_usage_tbytes() -> Option<f64> {
93    #[allow(clippy::cast_precision_loss)]
94    get_memory_usage_bytes().map(|m| m.get() as f64 / TERABYTE)
95}
96
97/// Application memory usage with unit
98///
99/// ```
100/// if let Some(usage) = app_memory_usage_fetcher::get_memory_usage_string() {
101///     println!("Memory usage: {usage}");
102/// }
103/// ```
104#[inline]
105#[must_use]
106pub fn get_memory_usage_string() -> Option<String> {
107    if let Some(bytes) = get_memory_usage_bytes() {
108        #[allow(clippy::cast_precision_loss)]
109        let bytes = bytes.get() as f64;
110        match bytes {
111            0.0..=KILOBYTE => Some(format!("{bytes:.2} bytes")),
112            KILOBYTE..=MEGABYTE => Some(format!("{:.2} KB", bytes / KILOBYTE)),
113            MEGABYTE..=GIGABYTE => Some(format!("{:.2} MB", bytes / MEGABYTE)),
114            GIGABYTE..=TERABYTE => Some(format!("{:.2} GB", bytes / GIGABYTE)),
115            _ => Some(format!("{:.2} TB", bytes / TERABYTE)),
116        }
117    } else {
118        None
119    }
120}