extern crate timer; extern crate termion; extern crate systemstat; use std::thread; use termion::{cursor, color, clear, terminal_size}; use termion::color::Color; use termion::raw::{IntoRawMode}; use termion::screen::{AlternateScreen}; use termion::async_stdin; use std::io::{Read, Write, stdout}; use std::time::{Duration, Instant}; use std::cmp::min; use systemstat::{System, Platform, Memory}; use systemstat::data::{LoadAverage}; fn update_values(value:T, values:&mut Vec, max_length:usize) { values.push(value); if values.len() > max_length { let number = values.len()-max_length; values.drain(0..number); } } fn print_cpu_load_time(stdout:&mut W, load_time:LoadAverage) { write!(stdout, "{}{}{}{} {}{} {}{}", cursor::Goto(1,3), clear::CurrentLine, color::Fg(color::Yellow), load_time.one, color::Fg(color::LightYellow), load_time.five, color::Fg(color::White), load_time.fifteen ).unwrap(); } fn print_mem_load(stdout:&mut W, memory:Memory) { write!(stdout, "{}{}{}{}/{}{}", cursor::Goto(1,4), clear::CurrentLine, color::Fg(color::Yellow), memory.total - memory.free, color::Fg(color::White), memory.total ).unwrap(); } fn print_graph(stdout:&mut W, values:&[f32], y_pos:u16, color:color::Fg) { const GRAPH:&'static str = "▁▂▃▄▅▆▇█"; write!(stdout, "{}{}{}", cursor::Goto(1, y_pos), clear::CurrentLine, color).unwrap(); for value in values { if *value <= 1. as f32 { let i:usize = (value * (GRAPH.chars().count() as f32)) as usize; match GRAPH.chars().nth(i) { Some(c) => write!(stdout, "{}", c).unwrap(), None => write!(stdout, "#").unwrap() } } else { write!(stdout, "{}█{}", color::Fg(color::Red), color).unwrap(); } } } fn main() { let mut screen = AlternateScreen::from(stdout().into_raw_mode().unwrap()); let mut stdin = async_stdin().bytes(); let system = System::new(); let mut cpu_load_graph:Vec = Vec::new(); let mut mem_load_graph:Vec = Vec::new(); let start_time = Instant::now(); let mut num_seconds:u64 = 0; let mut previous_size:(u16, u16) = (0,0); write!(screen, "{}", cursor::Hide).unwrap(); loop { let b = stdin.next(); match terminal_size() { Ok(size) => { if size != previous_size { write!(screen, "{}", clear::All).unwrap(); previous_size = size; } let x:usize = size.0 as usize & 0xFFFF; let new_time = start_time.elapsed().as_secs(); if new_time > num_seconds { let cpu = system.load_average(); if let Ok(cpu_load) = cpu { update_values(cpu_load.one, &mut cpu_load_graph, x); print_cpu_load_time(&mut screen, cpu_load); } if let Ok(mem_load) = system.memory() { update_values(((mem_load.total.as_usize() - mem_load.free.as_usize()) as f32) / (mem_load.total.as_usize() as f32), &mut mem_load_graph, x); print_mem_load(&mut screen, mem_load); } print_graph(&mut screen, &cpu_load_graph[0..min(x, cpu_load_graph.len())], 1, color::Fg(color::White)); print_graph(&mut screen, &mem_load_graph[0..min(x, mem_load_graph.len())], 2, color::Fg(color::Blue)); screen.flush().unwrap(); num_seconds = new_time; } if let Some(Ok(b'q')) = b { break; } thread::sleep(Duration::from_millis(50)); }, Err(e) => { println!("{}{}Error : {}", clear::All, cursor::Goto(1,1), e); break } } } write!(screen, "{}", cursor::Show).unwrap(); }