leenfetch_core/modules/linux/info/
memory.rs1use std::fs;
2
3use crate::modules::enums::MemoryUnit;
4
5pub fn get_memory(memory_percent: bool, memory_unit: MemoryUnit) -> Option<String> {
6 let contents = fs::read_to_string("/proc/meminfo").ok()?;
7
8 let mut mem_total_kb = 0;
9 let mut mem_available_kb = None;
10 let mut shmem = 0;
11 let mut memfree = 0;
12 let mut buffers = 0;
13 let mut cached = 0;
14 let mut sreclaimable = 0;
15
16 for line in contents.lines() {
17 let mut parts = line.split_whitespace();
18 match parts.next()? {
19 "MemTotal:" => mem_total_kb = parts.next()?.parse::<u64>().ok()?,
20 "MemAvailable:" => mem_available_kb = parts.next()?.parse::<u64>().ok(),
21 "Shmem:" => shmem = parts.next()?.parse::<u64>().ok()?,
22 "MemFree:" => memfree = parts.next()?.parse::<u64>().ok()?,
23 "Buffers:" => buffers = parts.next()?.parse::<u64>().ok()?,
24 "Cached:" => cached = parts.next()?.parse::<u64>().ok()?,
25 "SReclaimable:" => sreclaimable = parts.next()?.parse::<u64>().ok()?,
26 _ => {}
27 }
28 }
29
30 let used_kb = if let Some(avail) = mem_available_kb {
31 mem_total_kb.saturating_sub(avail)
32 } else {
33 mem_total_kb + shmem - memfree - buffers - cached - sreclaimable
34 };
35
36 let (used, total, unit_str) = match memory_unit {
37 MemoryUnit::GiB => (
38 used_kb as f64 / 1024.0 / 1024.0,
39 mem_total_kb as f64 / 1024.0 / 1024.0,
40 "GiB",
41 ),
42 MemoryUnit::KiB => (used_kb as f64, mem_total_kb as f64, "KiB"),
43 MemoryUnit::MiB => (used_kb as f64 / 1024.0, mem_total_kb as f64 / 1024.0, "MiB"),
44 };
45
46 let percent = if memory_percent {
47 format!(" ({:.0}%)", used / total * 100.0)
48 } else {
49 "".to_string()
50 };
51
52 Some(format!(
53 "{:.1}{} / {:.1}{}{}",
54 used, unit_str, total, unit_str, percent
55 ))
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_memory_output_mib() {
64 let result = get_memory(false, MemoryUnit::MiB);
65 assert!(result.is_some());
66 assert!(result.unwrap().contains("MiB"));
67 }
68
69 #[test]
70 fn test_memory_output_gib_with_percent() {
71 let result = get_memory(true, MemoryUnit::GiB);
72 let output = result.unwrap();
73 assert!(output.contains("GiB"));
74 assert!(output.contains('%'));
75 }
76
77 #[test]
78 fn test_memory_output_kib() {
79 let result = get_memory(false, MemoryUnit::KiB);
80 assert!(result.unwrap().contains("KiB"));
81 }
82}