rs_blocks/blocks/
memory.rs1use crate::blocks::{Block, Configure, Message, Sender};
25use crate::{ema, utils};
26use regex::Regex;
27use serde::Deserialize;
28use std::thread;
29
30const MEMPATH: &str = "/proc/meminfo";
31const PATTERN: &str = r"(?s)MemTotal:\s+(\d+).+MemFree:\s+(\d+)";
32
33#[derive(Configure, Deserialize)]
34pub struct Memory {
35 #[serde(default = "default_name")]
36 name: String,
37 #[serde(default = "default_period")]
38 period: f32,
39 #[serde(default = "default_alpha")]
40 alpha: f32,
41}
42
43fn default_name() -> String {
44 "memory".to_string()
45}
46
47fn default_period() -> f32 {
48 1.0
49}
50
51fn default_alpha() -> f32 {
52 0.5
53}
54
55impl Sender for Memory {
56 fn add_sender(&self, channel: crossbeam_channel::Sender<Message>) -> anyhow::Result<()> {
57 let name = self.get_name();
58 let monitor = utils::monitor_file(MEMPATH.to_string(), self.period);
59 let mut mem = ema::Ema::new(self.alpha);
60 let mut block = Block::new(name.clone(), true);
61
62 thread::spawn(move || {
63 for text in monitor {
64 let perc = get_mem_percentage(match_mem_stats(&text));
65 block.full_text = Some(format!(" {:.1}%", mem.push(perc) * 100.0));
66 channel.send((name.clone(), block.to_string())).unwrap();
67 }
68 });
69
70 Ok(())
71 }
72}
73
74#[derive(Debug, PartialEq)]
75struct MemStats {
76 total: f64,
77 free: f64,
78}
79
80fn match_mem_stats(s: &str) -> MemStats {
81 lazy_static! {
82 static ref RE: Regex = Regex::new(PATTERN).unwrap();
83 }
84 let caps = RE.captures(s).unwrap();
85 MemStats {
86 total: caps.get(1).unwrap().as_str().parse().unwrap(),
87 free: caps.get(2).unwrap().as_str().parse().unwrap(),
88 }
89}
90
91fn get_mem_percentage(mem: MemStats) -> f32 {
92 1.0 - mem.free as f32 / mem.total as f32
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 const MEMFILE: &str = "MemTotal: 16134372 kB\nMemFree: 2757408 kB\n";
99
100 #[test]
101 fn regex_matches() {
102 let mem = match_mem_stats(&MEMFILE);
103 assert_eq!(
104 mem,
105 MemStats {
106 total: 16134372.0,
107 free: 2757408.0
108 }
109 );
110 }
111}