33// For the full copyright and license information, please view the LICENSE
44// file that was distributed with this source code.
55
6+ use crate :: picker:: systemstat;
7+ use bytesize:: ByteSize ;
68use clap:: { arg, crate_version, value_parser, ArgAction , ArgGroup , ArgMatches , Command } ;
79use picker:: pickers;
810use picker:: sysinfo;
911use prettytable:: { format:: consts:: FORMAT_CLEAN , Row , Table } ;
1012use std:: { thread:: sleep, time:: Duration } ;
1113use sysinfo:: { Pid , Users } ;
14+ use systemstat:: { CPULoad , Platform } ;
1215use uucore:: {
1316 error:: { UResult , USimpleError } ,
1417 format_usage, help_about, help_usage,
@@ -53,8 +56,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
5356 // Must refresh twice.
5457 // https://docs.rs/sysinfo/0.31.2/sysinfo/struct.System.html#method.refresh_cpu_usage
5558 picker:: sysinfo ( ) . write ( ) . unwrap ( ) . refresh_all ( ) ;
59+ let cpu_load = systemstat ( ) . read ( ) . unwrap ( ) . cpu_load_aggregate ( ) ?;
5660 sleep ( Duration :: from_millis ( 200 ) ) ;
5761 picker:: sysinfo ( ) . write ( ) . unwrap ( ) . refresh_all ( ) ;
62+ let cpu_load = cpu_load. done ( ) ?;
5863
5964 let settings = Settings :: new ( & matches) ;
6065
@@ -97,7 +102,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
97102 table
98103 } ;
99104
100- println ! ( "{}" , header( ) ) ;
105+ println ! ( "{}" , header( cpu_load ) ) ;
101106 println ! ( "\n " ) ;
102107
103108 let cutter = {
@@ -113,11 +118,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
113118 }
114119 } ;
115120
116- table
117- . to_string ( )
118- . lines ( )
119- . map ( cutter)
120- . for_each ( |it| println ! ( "{}" , it) ) ;
121+ table. to_string ( ) . lines ( ) . map ( cutter) . for_each ( |_| { } ) ;
122+ // .for_each(|it| println!("{}", it));
121123
122124 Ok ( ( ) )
123125}
@@ -157,9 +159,79 @@ where
157159 }
158160}
159161
162+ fn format_uptime ( duration : Duration ) -> String {
163+ let mut num = duration. as_secs ( ) ;
164+ if num < 60 {
165+ return format ! ( "{} s" , num) ;
166+ }
167+
168+ num /= 60 ; //to minutes
169+ if num < 60 {
170+ return format ! ( "{} m" , num) ;
171+ }
172+ if num < 600 {
173+ return format ! ( "{}:{:2}" , num / 60 , num % 60 ) ;
174+ }
175+
176+ num /= 60 ; //to hours
177+ if num < 24 {
178+ format ! ( "{} h" , num)
179+ } else {
180+ num /= 24 ; //to days
181+ format ! ( "{} d" , num)
182+ }
183+ }
184+
160185// TODO: Implement information collecting.
161- fn header ( ) -> String {
162- "TODO" . into ( )
186+ fn header ( cpu_load : CPULoad ) -> String {
187+ let systemstat = systemstat ( ) . read ( ) . unwrap ( ) ;
188+ let sysinfo = sysinfo ( ) . read ( ) . unwrap ( ) ;
189+ let process = sysinfo. processes ( ) ;
190+ let mut running_process = 0 ;
191+ let mut sleeping_process = 0 ;
192+ let mut stopped_process = 0 ;
193+ let mut zombie_process = 0 ;
194+ for ( _, process) in process. iter ( ) {
195+ match process. status ( ) {
196+ sysinfo:: ProcessStatus :: Run => running_process += 1 ,
197+ sysinfo:: ProcessStatus :: Sleep => sleeping_process += 1 ,
198+ sysinfo:: ProcessStatus :: Stop => stopped_process += 1 ,
199+ sysinfo:: ProcessStatus :: Zombie => zombie_process += 1 ,
200+ _ => { }
201+ } ;
202+ }
203+
204+ //, {} hi, {} si, {} st
205+ format ! (
206+ "top - {} up {}, %n user, load average: {:.2}, {:.2}, {:.2}\n \
207+ Tasks: {} total, {} running, {} sleeping, {} stopped, {} zombie\n \
208+ %Cpu(s): {:.1} us, {:.1} sy, {:.1} ni, {:.1} id, {:.1} wa\n \
209+ MiB Mem : {:8.1} total, {:8.1} free, {:8.1} used, {:8.1} buff/cache\n \
210+ MiB Swap: {:8.1} total, {:8.1} free, {:8.1} used, {:8.1} avail Mem\n ",
211+ chrono:: Local :: now( ) . format( "%H:%M:%S" ) ,
212+ format_uptime( systemstat. uptime( ) . unwrap( ) ) ,
213+ systemstat. load_average( ) . unwrap( ) . one,
214+ systemstat. load_average( ) . unwrap( ) . five,
215+ systemstat. load_average( ) . unwrap( ) . fifteen,
216+ process. len( ) ,
217+ running_process,
218+ sleeping_process,
219+ stopped_process,
220+ zombie_process,
221+ cpu_load. user * 100.0 ,
222+ cpu_load. system * 100.0 ,
223+ cpu_load. nice * 100.0 ,
224+ cpu_load. idle * 100.0 ,
225+ cpu_load. platform. iowait * 100.0 ,
226+ ByteSize :: b( sysinfo. total_memory( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
227+ ByteSize :: b( sysinfo. free_memory( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
228+ ByteSize :: b( sysinfo. used_memory( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
229+ ByteSize :: b( sysinfo. total_memory( ) - sysinfo. free_memory( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
230+ ByteSize :: b( sysinfo. total_swap( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
231+ ByteSize :: b( sysinfo. free_swap( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
232+ ByteSize :: b( sysinfo. used_swap( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
233+ ByteSize :: b( sysinfo. total_memory( ) - sysinfo. free_memory( ) ) . 0 as f64 / bytesize:: MIB as f64 ,
234+ )
163235}
164236
165237// TODO: Implement fields selecting
0 commit comments