|
5 | 5 |
|
6 | 6 | use crate::picker::sysinfo; |
7 | 7 | use crate::platform::*; |
8 | | -use crate::{CpuGraphMode, CpuValueMode, MemoryGraphMode, Settings}; |
| 8 | +use crate::tui::stat::{CpuValueMode, TuiStat}; |
9 | 9 | use bytesize::ByteSize; |
10 | 10 | use uu_vmstat::CpuLoad; |
11 | 11 | use uu_w::get_formatted_uptime_procps; |
12 | 12 | use uucore::uptime::{get_formatted_loadavg, get_formatted_nusers, get_formatted_time}; |
13 | 13 |
|
14 | | -pub(crate) fn header(settings: &Settings) -> String { |
15 | | - let uptime_line = format!( |
16 | | - "top - {time} {uptime}, {user}, {load_average}\n", |
17 | | - time = get_formatted_time(), |
18 | | - uptime = uptime(), |
19 | | - user = user(), |
20 | | - load_average = load_average(), |
21 | | - ); |
22 | | - |
23 | | - let task_and_cpu = if settings.cpu_graph_mode == CpuGraphMode::Hide { |
24 | | - String::new() |
25 | | - } else { |
26 | | - format!( |
27 | | - "{task}\n\ |
28 | | - {cpu}\n", |
29 | | - task = task(), |
30 | | - cpu = cpu(settings), |
31 | | - ) |
32 | | - }; |
| 14 | +pub(crate) struct Header { |
| 15 | + pub uptime: Uptime, |
| 16 | + pub task: Task, |
| 17 | + pub cpu: Vec<(String, CpuLoad)>, |
| 18 | + pub memory: Memory, |
| 19 | +} |
33 | 20 |
|
34 | | - let memory_line = if settings.memory_graph_mode == MemoryGraphMode::Hide { |
35 | | - String::new() |
36 | | - } else { |
37 | | - memory(settings) |
38 | | - }; |
| 21 | +impl Header { |
| 22 | + pub fn new(stat: &TuiStat) -> Header { |
| 23 | + Header { |
| 24 | + uptime: Uptime::new(), |
| 25 | + task: Task::new(), |
| 26 | + cpu: cpu(stat), |
| 27 | + memory: Memory::new(), |
| 28 | + } |
| 29 | + } |
39 | 30 |
|
40 | | - format!("{uptime_line}{task_and_cpu}{memory_line}") |
| 31 | + pub fn update_cpu(&mut self, stat: &TuiStat) { |
| 32 | + self.cpu = cpu(stat); |
| 33 | + } |
41 | 34 | } |
42 | 35 |
|
43 | | -fn format_memory(memory_b: u64, unit: u64) -> f64 { |
44 | | - ByteSize::b(memory_b).0 as f64 / unit as f64 |
| 36 | +pub(crate) struct Uptime { |
| 37 | + pub time: String, |
| 38 | + pub uptime: String, |
| 39 | + pub user: String, |
| 40 | + pub load_average: String, |
45 | 41 | } |
46 | 42 |
|
47 | | -#[inline] |
48 | | -fn uptime() -> String { |
49 | | - get_formatted_uptime_procps().unwrap_or_default() |
| 43 | +impl Uptime { |
| 44 | + pub fn new() -> Uptime { |
| 45 | + Uptime { |
| 46 | + time: get_formatted_time(), |
| 47 | + uptime: get_formatted_uptime_procps().unwrap_or_default(), |
| 48 | + user: user(), |
| 49 | + load_average: get_formatted_loadavg().unwrap_or_default(), |
| 50 | + } |
| 51 | + } |
50 | 52 | } |
51 | 53 |
|
52 | | -// see: https://gitlab.com/procps-ng/procps/-/blob/4740a0efa79cade867cfc7b32955fe0f75bf5173/library/uptime.c#L63-L115 |
53 | | -fn user() -> String { |
54 | | - #[cfg(target_os = "linux")] |
55 | | - if let Ok(nusers) = get_nusers_systemd() { |
56 | | - return uucore::uptime::format_nusers(nusers); |
| 54 | +pub(crate) struct Task { |
| 55 | + pub total: usize, |
| 56 | + pub running: usize, |
| 57 | + pub sleeping: usize, |
| 58 | + pub stopped: usize, |
| 59 | + pub zombie: usize, |
| 60 | +} |
| 61 | +impl Task { |
| 62 | + pub fn new() -> Task { |
| 63 | + let binding = sysinfo().read().unwrap(); |
| 64 | + |
| 65 | + let process = binding.processes(); |
| 66 | + let mut running_process = 0; |
| 67 | + let mut sleeping_process = 0; |
| 68 | + let mut stopped_process = 0; |
| 69 | + let mut zombie_process = 0; |
| 70 | + |
| 71 | + for (_, process) in process.iter() { |
| 72 | + match process.status() { |
| 73 | + sysinfo::ProcessStatus::Run => running_process += 1, |
| 74 | + sysinfo::ProcessStatus::Sleep => sleeping_process += 1, |
| 75 | + sysinfo::ProcessStatus::Stop => stopped_process += 1, |
| 76 | + sysinfo::ProcessStatus::Zombie => zombie_process += 1, |
| 77 | + _ => {} |
| 78 | + }; |
| 79 | + } |
| 80 | + |
| 81 | + Task { |
| 82 | + total: process.len(), |
| 83 | + running: running_process, |
| 84 | + sleeping: sleeping_process, |
| 85 | + stopped: stopped_process, |
| 86 | + zombie: zombie_process, |
| 87 | + } |
57 | 88 | } |
| 89 | +} |
58 | 90 |
|
59 | | - get_formatted_nusers() |
| 91 | +pub(crate) struct Memory { |
| 92 | + pub total: u64, |
| 93 | + pub free: u64, |
| 94 | + pub used: u64, |
| 95 | + pub buff_cache: u64, |
| 96 | + pub available: u64, |
| 97 | + pub total_swap: u64, |
| 98 | + pub free_swap: u64, |
| 99 | + pub used_swap: u64, |
60 | 100 | } |
61 | 101 |
|
62 | | -fn load_average() -> String { |
63 | | - get_formatted_loadavg().unwrap_or_default() |
| 102 | +impl Memory { |
| 103 | + pub fn new() -> Memory { |
| 104 | + get_memory() |
| 105 | + } |
64 | 106 | } |
65 | 107 |
|
66 | | -fn task() -> String { |
67 | | - let binding = sysinfo().read().unwrap(); |
68 | | - |
69 | | - let process = binding.processes(); |
70 | | - let mut running_process = 0; |
71 | | - let mut sleeping_process = 0; |
72 | | - let mut stopped_process = 0; |
73 | | - let mut zombie_process = 0; |
74 | | - |
75 | | - for (_, process) in process.iter() { |
76 | | - match process.status() { |
77 | | - sysinfo::ProcessStatus::Run => running_process += 1, |
78 | | - sysinfo::ProcessStatus::Sleep => sleeping_process += 1, |
79 | | - sysinfo::ProcessStatus::Stop => stopped_process += 1, |
80 | | - sysinfo::ProcessStatus::Zombie => zombie_process += 1, |
81 | | - _ => {} |
82 | | - }; |
| 108 | +pub(crate) fn format_memory(memory_b: u64, unit: u64) -> f64 { |
| 109 | + ByteSize::b(memory_b).0 as f64 / unit as f64 |
| 110 | +} |
| 111 | + |
| 112 | +// see: https://gitlab.com/procps-ng/procps/-/blob/4740a0efa79cade867cfc7b32955fe0f75bf5173/library/uptime.c#L63-L115 |
| 113 | +fn user() -> String { |
| 114 | + #[cfg(target_os = "linux")] |
| 115 | + if let Ok(nusers) = get_nusers_systemd() { |
| 116 | + return uucore::uptime::format_nusers(nusers); |
83 | 117 | } |
84 | 118 |
|
85 | | - format!( |
86 | | - "Tasks: {} total, {} running, {} sleeping, {} stopped, {} zombie", |
87 | | - process.len(), |
88 | | - running_process, |
89 | | - sleeping_process, |
90 | | - stopped_process, |
91 | | - zombie_process, |
92 | | - ) |
| 119 | + get_formatted_nusers() |
93 | 120 | } |
94 | 121 |
|
95 | 122 | fn sum_cpu_loads(cpu_loads: &[uu_vmstat::CpuLoadRaw]) -> uu_vmstat::CpuLoadRaw { |
@@ -122,94 +149,22 @@ fn sum_cpu_loads(cpu_loads: &[uu_vmstat::CpuLoadRaw]) -> uu_vmstat::CpuLoadRaw { |
122 | 149 | total |
123 | 150 | } |
124 | 151 |
|
125 | | -fn cpu(settings: &Settings) -> String { |
126 | | - if settings.cpu_graph_mode == CpuGraphMode::Hide { |
127 | | - return String::new(); |
128 | | - } |
129 | | - |
| 152 | +fn cpu(stat: &TuiStat) -> Vec<(String, CpuLoad)> { |
130 | 153 | let cpu_loads = get_cpu_loads(); |
131 | 154 |
|
132 | | - match settings.cpu_value_mode { |
133 | | - CpuValueMode::PerCore => { |
134 | | - let lines = cpu_loads |
135 | | - .iter() |
136 | | - .enumerate() |
137 | | - .map(|(nth, cpu_load_raw)| { |
138 | | - let cpu_load = CpuLoad::from_raw(cpu_load_raw); |
139 | | - cpu_line(format!("Cpu{nth}").as_str(), &cpu_load, settings) |
140 | | - }) |
141 | | - .collect::<Vec<String>>(); |
142 | | - lines.join("\n") |
143 | | - } |
| 155 | + match stat.cpu_value_mode { |
| 156 | + CpuValueMode::PerCore => cpu_loads |
| 157 | + .iter() |
| 158 | + .enumerate() |
| 159 | + .map(|(nth, cpu_load_raw)| { |
| 160 | + let cpu_load = CpuLoad::from_raw(cpu_load_raw); |
| 161 | + (format!("Cpu{nth}"), cpu_load) |
| 162 | + }) |
| 163 | + .collect::<Vec<(String, CpuLoad)>>(), |
144 | 164 | CpuValueMode::Sum => { |
145 | 165 | let total = sum_cpu_loads(&cpu_loads); |
146 | 166 | let cpu_load = CpuLoad::from_raw(&total); |
147 | | - cpu_line("Cpu", &cpu_load, settings) |
| 167 | + vec![(String::from("Cpu(s)"), cpu_load)] |
148 | 168 | } |
149 | 169 | } |
150 | 170 | } |
151 | | - |
152 | | -fn cpu_line(tag: &str, cpu_load: &CpuLoad, settings: &Settings) -> String { |
153 | | - if settings.cpu_graph_mode == CpuGraphMode::Hide { |
154 | | - return String::new(); |
155 | | - } |
156 | | - |
157 | | - if settings.cpu_graph_mode == CpuGraphMode::Sum { |
158 | | - return format!( |
159 | | - "%{tag:<6}: {:.1} us, {:.1} sy, {:.1} ni, {:.1} id, {:.1} wa, {:.1} hi, {:.1} si, {:.1} st", |
160 | | - cpu_load.user, |
161 | | - cpu_load.system, |
162 | | - cpu_load.nice, |
163 | | - cpu_load.idle, |
164 | | - cpu_load.io_wait, |
165 | | - cpu_load.hardware_interrupt, |
166 | | - cpu_load.software_interrupt, |
167 | | - cpu_load.steal_time, |
168 | | - ); |
169 | | - } |
170 | | - |
171 | | - // TODO: render colored bar chart or block chart |
172 | | - format!("%{tag:<6}: {:>5.1}/{:<5.1}", cpu_load.user, cpu_load.system) |
173 | | -} |
174 | | - |
175 | | -fn memory(settings: &Settings) -> String { |
176 | | - let binding = sysinfo().read().unwrap(); |
177 | | - let (unit, unit_name) = match settings.scale_summary_mem.as_ref() { |
178 | | - Some(scale) => match scale.as_str() { |
179 | | - "k" => (bytesize::KIB, "KiB"), |
180 | | - "m" => (bytesize::MIB, "MiB"), |
181 | | - "g" => (bytesize::GIB, "GiB"), |
182 | | - "t" => (bytesize::TIB, "TiB"), |
183 | | - "p" => (bytesize::PIB, "PiB"), |
184 | | - "e" => (1_152_921_504_606_846_976, "EiB"), |
185 | | - _ => (bytesize::MIB, "MiB"), |
186 | | - }, |
187 | | - None => (bytesize::MIB, "MiB"), |
188 | | - }; |
189 | | - |
190 | | - if settings.memory_graph_mode == MemoryGraphMode::Sum { |
191 | | - return format!( |
192 | | - "{unit_name} Mem : {:8.1} total, {:8.1} free, {:8.1} used, {:8.1} buff/cache\n\ |
193 | | - {unit_name} Swap: {:8.1} total, {:8.1} free, {:8.1} used, {:8.1} avail Mem", |
194 | | - format_memory(binding.total_memory(), unit), |
195 | | - format_memory(binding.free_memory(), unit), |
196 | | - format_memory(binding.used_memory(), unit), |
197 | | - format_memory(binding.available_memory() - binding.free_memory(), unit), |
198 | | - format_memory(binding.total_swap(), unit), |
199 | | - format_memory(binding.free_swap(), unit), |
200 | | - format_memory(binding.used_swap(), unit), |
201 | | - format_memory(binding.available_memory(), unit), |
202 | | - unit_name = unit_name |
203 | | - ); |
204 | | - } |
205 | | - |
206 | | - // TODO: render colored bar chart or block chart |
207 | | - format!( |
208 | | - "GiB Mem : {:>5.1}/{:<5.1}\n\ |
209 | | - GiB Swap : {:>5.1}/{:<5.1}", |
210 | | - format_memory(binding.used_memory(), unit), |
211 | | - format_memory(binding.total_memory(), unit), |
212 | | - format_memory(binding.used_swap(), unit), |
213 | | - format_memory(binding.total_swap(), unit) |
214 | | - ) |
215 | | -} |
0 commit comments