//! Data collection for memory via heim. #[derive(Debug, Clone, Default)] pub struct MemHarvest { pub mem_total_in_kib: u64, pub mem_used_in_kib: u64, pub use_percent: Option, } pub async fn get_mem_data( actually_get: bool, ) -> ( crate::utils::error::Result>, crate::utils::error::Result>, ) { use futures::join; if !actually_get { (Ok(None), Ok(None)) } else { join!(get_ram_data(), get_swap_data()) } } pub async fn get_ram_data() -> crate::utils::error::Result> { let memory = heim::memory::memory().await?; let (mem_total_in_kib, mem_used_in_kib) = { #[cfg(target_os = "linux")] { use heim::memory::os::linux::MemoryExt; use heim::units::information::kilobyte; // For Linux, the "kilobyte" value in the .total call is actually kibibytes - see // https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo // // Heim parses this as kilobytes (https://github.com/heim-rs/heim/blob/master/heim-memory/src/sys/linux/memory.rs#L82) // even though it probably shouldn't... ( memory.total().get::(), memory.used().get::(), ) } #[cfg(target_os = "macos")] { use heim::memory::os::macos::MemoryExt; use heim::units::information::kibibyte; ( memory.total().get::(), memory.active().get::() + memory.wire().get::(), ) } #[cfg(target_os = "windows")] { use heim::units::information::kibibyte; let mem_total_in_kib = memory.total().get::(); ( mem_total_in_kib, mem_total_in_kib - memory.available().get::(), ) } }; Ok(Some(MemHarvest { mem_total_in_kib, mem_used_in_kib, use_percent: if mem_total_in_kib == 0 { None } else { Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0) }, })) } pub async fn get_swap_data() -> crate::utils::error::Result> { let memory = heim::memory::swap().await?; let (mem_total_in_kib, mem_used_in_kib) = { #[cfg(target_os = "linux")] { // Similar story to above - heim parses this information incorrectly as far as I can tell, so kilobytes = kibibytes here. use heim::units::information::kilobyte; ( memory.total().get::(), memory.used().get::(), ) } #[cfg(any(target_os = "windows", target_os = "macos"))] { use heim::units::information::kibibyte; ( memory.total().get::(), memory.used().get::(), ) } }; Ok(Some(MemHarvest { mem_total_in_kib, mem_used_in_kib, use_percent: if mem_total_in_kib == 0 { None } else { Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0) }, })) }