diff --git a/Cargo.lock b/Cargo.lock index 179a323..d173257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -317,6 +317,15 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ctrlc" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dirs" version = "2.0.1" @@ -1004,6 +1013,7 @@ dependencies = [ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossterm 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fern 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "heim 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1505,6 +1515,7 @@ dependencies = [ "checksum crossterm_terminal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "18792c97c5cdcc5fd3582df58188a793bf290af4a53d5fc8442c7d17e003b356" "checksum crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8321d40908d0ee77cb29335f591eae2b4f7225152f81b9dfa35a161ca3b077dc" "checksum crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c061e4a1c47a53952ba0f2396c00a61cd7ab74482eba99b9c9cc77fdca71932" +"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" "checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1" "checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d" "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" diff --git a/Cargo.toml b/Cargo.toml index 563d0e7..22e40d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" chrono = "0.4.7" crossbeam-channel = "0.3" crossterm = "0.9.6" +ctrlc = { version = "3.1.3", features = ["termination"] } fern = "0.5.8" futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } heim = "0.0.4" diff --git a/src/main.rs b/src/main.rs index 983d007..3906a32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod widgets; use std::fs; use std::io; use std::path::Path; +use std::process::exit; use std::thread; use std::time::Duration; @@ -49,25 +50,34 @@ fn setup_terminal() -> io::Result> { fn setup_ui_events() -> Receiver { let (ui_events_sender, ui_events_receiver) = unbounded(); thread::spawn(move || { - let _screen = crossterm::RawScreen::into_raw_mode().unwrap(); // TODO: unwrap + let _screen = crossterm::RawScreen::into_raw_mode().unwrap(); let input = crossterm::input(); - input.enable_mouse_mode().unwrap(); // TODO: unwrap + input.enable_mouse_mode().unwrap(); let mut reader = input.read_sync(); loop { - ui_events_sender.send(reader.next().unwrap()).unwrap(); // TODO: unwraps + ui_events_sender.send(reader.next().unwrap()).unwrap(); } }); ui_events_receiver } +fn setup_ctrl_c() -> Result, ctrlc::Error> { + let (sender, receiver) = unbounded(); + ctrlc::set_handler(move || { + sender.send(()).unwrap(); + })?; + + Ok(receiver) +} + fn setup_logfile(logfile_path: &Path) { - fs::create_dir_all(logfile_path.parent().unwrap()).unwrap(); // TODO: unwrap + fs::create_dir_all(logfile_path.parent().unwrap()).unwrap(); let logfile = fs::OpenOptions::new() .write(true) .create(true) .truncate(true) .open(logfile_path) - .unwrap(); // TODO: unwrap + .unwrap(); fern::Dispatch::new() .format(|out, message, record| { out.finish(format_args!( @@ -80,7 +90,7 @@ fn setup_logfile(logfile_path: &Path) { }) .chain(logfile) .apply() - .unwrap(); // TODO: unwrap + .unwrap(); } fn read_colorscheme( @@ -89,7 +99,7 @@ fn read_colorscheme( ) -> serde_json::Result { match colorscheme { args::Colorscheme::Custom(name) => serde_json::from_str( - &fs::read_to_string(config_folder.join(name).with_extension("json")).unwrap(), // TODO: unwrap + &fs::read_to_string(config_folder.join(name).with_extension("json")).unwrap(), ), _ => { let json_string = match colorscheme { @@ -102,7 +112,8 @@ fn read_colorscheme( args::Colorscheme::Vice => include_str!("../colorschemes/vice.json"), _ => unreachable!(), }; - Ok(serde_json::from_str(json_string).unwrap()) + Ok(serde_json::from_str(json_string) + .expect("statically defined and verified json colorschemes")) } } } @@ -182,12 +193,12 @@ fn draw_widgets(terminal: &mut Terminal, widgets: &mut Widgets) - widgets .disk_widget .as_mut() - .unwrap() // TODO: unwrap + .unwrap() .render(&mut frame, middle_left_vertical_chunks[0]); widgets .temp_widget .as_mut() - .unwrap() // TODO: unwrap + .unwrap() .render(&mut frame, middle_left_vertical_chunks[1]); let bottom_horizontal_chunks = Layout::default() .direction(Direction::Horizontal) @@ -196,7 +207,7 @@ fn draw_widgets(terminal: &mut Terminal, widgets: &mut Widgets) - widgets .net_widget .as_mut() - .unwrap() // TODO: unwrap + .unwrap() .render(&mut frame, bottom_horizontal_chunks[0]); widgets .proc_widget @@ -217,33 +228,37 @@ async fn main() { let mut show_help_menu = false; let program_name = env!("CARGO_PKG_NAME"); - let app_dirs = AppDirs::new(Some(program_name), AppUI::CommandLine).unwrap(); // TODO: unwrap + let app_dirs = AppDirs::new(Some(program_name), AppUI::CommandLine).unwrap(); let logfile_path = app_dirs.state_dir.join("errors.log"); - let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap(); // TODO: unwrap + let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap(); let mut widgets = setup_widgets(&args, &colorscheme); setup_logfile(&logfile_path); - let mut terminal = setup_terminal().unwrap(); // TODO: unwrap + let mut terminal = setup_terminal().unwrap(); let mut ticks = 0; let ticker = tick(Duration::from_secs(1)); let ui_events_receiver = setup_ui_events(); + let ctrl_c_events = setup_ctrl_c().unwrap(); update_widgets(&mut widgets, ticks).await; - draw_widgets(&mut terminal, &mut widgets).unwrap(); // TODO: unwrap + draw_widgets(&mut terminal, &mut widgets).unwrap(); loop { select! { + recv(ctrl_c_events) -> _ => { + break; + } recv(ticker) -> _ => { ticks = (ticks + 1) % 60; update_widgets(&mut widgets, ticks).await; if !show_help_menu { - draw_widgets(&mut terminal, &mut widgets).unwrap(); // TODO: unwrap + draw_widgets(&mut terminal, &mut widgets).unwrap(); } } recv(ui_events_receiver) -> message => { - match message.unwrap() { // TODO: unwrap + match message.unwrap() { InputEvent::Keyboard(key_event) => { match key_event { KeyEvent::Char(c) => match c { @@ -251,9 +266,9 @@ async fn main() { '?' => { show_help_menu = !show_help_menu; if show_help_menu { - draw_help_menu(&mut terminal, &mut widgets.help_menu).unwrap(); // TODO: unwrap + draw_help_menu(&mut terminal, &mut widgets.help_menu).unwrap(); } else { - draw_widgets(&mut terminal, &mut widgets).unwrap(); // TODO: unwrap + draw_widgets(&mut terminal, &mut widgets).unwrap(); } }, _ => {} @@ -265,7 +280,7 @@ async fn main() { KeyEvent::Esc => { if show_help_menu { show_help_menu = false; - draw_widgets(&mut terminal, &mut widgets).unwrap(); // TODO: unwrap + draw_widgets(&mut terminal, &mut widgets).unwrap(); } } _ => {}