summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorremgodow <remgodow@users.noreply.github.com>2020-09-03 18:17:18 +0200
committerGitHub <noreply@github.com>2020-09-03 18:17:18 +0200
commit1db74c81ebf20847b90d585b86ed1314496c7aec (patch)
treea7207627c5eb946aa6838490f162a7a90825357e /src
parentb275ee61e11c3404c84868e85b1a52b8dd231d03 (diff)
feat(infra): replace termion with Windows compatible crossterm (#179)
* Replace termion backend with crossterm, which works on Windows as well. * Remove tui default-features (termion), update unit tests for crossterm. * Fix formatting.
Diffstat (limited to 'src')
-rw-r--r--src/main.rs36
-rw-r--r--src/os/shared.rs12
-rw-r--r--src/tests/cases/test_utils.rs7
-rw-r--r--src/tests/cases/ui.rs27
-rw-r--r--src/tests/fakes/fake_input.rs2
5 files changed, 59 insertions, 25 deletions
diff --git a/src/main.rs b/src/main.rs
index 586b9d0..966e871 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,21 +13,20 @@ use network::{
};
use os::OnSigWinch;
+use ::crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
+use ::crossterm::terminal;
use ::pnet::datalink::{DataLinkReceiver, NetworkInterface};
use ::std::collections::HashMap;
use ::std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use ::std::sync::{Arc, Mutex};
use ::std::thread;
use ::std::thread::park_timeout;
-use ::termion::event::{Event, Key};
use ::tui::backend::Backend;
use std::process;
-use ::std::io;
use ::std::time::{Duration, Instant};
-use ::termion::raw::IntoRawMode;
-use ::tui::backend::TermionBackend;
+use ::tui::backend::CrosstermBackend;
use std::sync::RwLock;
use structopt::StructOpt;
@@ -87,9 +86,9 @@ fn try_main() -> Result<(), failure::Error> {
let terminal_backend = RawTerminalBackend {};
start(terminal_backend, os_input, opts);
} else {
- match io::stdout().into_raw_mode() {
- Ok(stdout) => {
- let terminal_backend = TermionBackend::new(stdout);
+ match terminal::enable_raw_mode() {
+ Ok(()) => {
+ let terminal_backend = CrosstermBackend::new();
start(terminal_backend, os_input, opts);
}
Err(_) => failure::bail!(
@@ -250,13 +249,27 @@ where
let mut ui = ui.lock().unwrap();
match evt {
- Event::Key(Key::Ctrl('c')) | Event::Key(Key::Char('q')) => {
+ Event::Key(KeyEvent {
+ modifiers: KeyModifiers::CONTROL,
+ code: KeyCode::Char('c'),
+ })
+ | Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Char('q'),
+ }) => {
running.store(false, Ordering::Release);
cleanup();
display_handler.unpark();
+ match terminal::disable_raw_mode() {
+ Ok(_) => {}
+ Err(_) => println!("Error could not disable raw input"),
+ }
break;
}
- Event::Key(Key::Char(' ')) => {
+ Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Char(' '),
+ }) => {
let restarting = paused.fetch_xor(true, Ordering::SeqCst);
if restarting {
*last_start_time.write().unwrap() = Instant::now();
@@ -271,7 +284,10 @@ where
display_handler.unpark();
}
- Event::Key(Key::Char('\t')) => {
+ Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Tab,
+ }) => {
let paused = paused.load(Ordering::SeqCst);
let elapsed_time = elapsed_time(
*last_start_time.read().unwrap(),
diff --git a/src/os/shared.rs b/src/os/shared.rs
index 462f269..7c252bf 100644
--- a/src/os/shared.rs
+++ b/src/os/shared.rs
@@ -1,9 +1,9 @@
+use ::crossterm::event::read;
+use ::crossterm::event::Event;
use ::pnet::datalink::Channel::Ethernet;
use ::pnet::datalink::DataLinkReceiver;
use ::pnet::datalink::{self, Config, NetworkInterface};
-use ::std::io::{self, stdin, ErrorKind, Write};
-use ::termion::event::Event;
-use ::termion::input::TermRead;
+use ::std::io::{self, ErrorKind, Write};
use ::tokio::runtime::Runtime;
use ::std::time;
@@ -25,9 +25,9 @@ pub struct KeyboardEvents;
impl Iterator for KeyboardEvents {
type Item = Event;
fn next(&mut self) -> Option<Event> {
- match stdin().events().next() {
- Some(Ok(ev)) => Some(ev),
- _ => None,
+ match read() {
+ Ok(ev) => Some(ev),
+ Err(_) => None,
}
}
}
diff --git a/src/tests/cases/test_utils.rs b/src/tests/cases/test_utils.rs
index 50cd30e..7982a2d 100644
--- a/src/tests/cases/test_utils.rs
+++ b/src/tests/cases/test_utils.rs
@@ -6,7 +6,7 @@ use std::iter;
use crate::network::dns::Client;
use crate::{Opt, OsInputOutput, RenderOpts};
-use ::termion::event::{Event, Key};
+use ::crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use packet_builder::*;
use pnet::datalink::DataLinkReceiver;
use std::collections::HashMap;
@@ -19,7 +19,10 @@ use pnet_base::MacAddr;
pub fn sleep_and_quit_events(sleep_num: usize) -> Box<KeyboardEvents> {
let mut events: Vec<Option<Event>> = iter::repeat(None).take(sleep_num).collect();
- events.push(Some(Event::Key(Key::Ctrl('c'))));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::CONTROL,
+ code: KeyCode::Char('c'),
+ })));
Box::new(KeyboardEvents::new(events))
}
diff --git a/src/tests/cases/ui.rs b/src/tests/cases/ui.rs
index d3df052..1037a67 100644
--- a/src/tests/cases/ui.rs
+++ b/src/tests/cases/ui.rs
@@ -12,7 +12,7 @@ use crate::tests::cases::test_utils::{
build_tcp_packet, opts_ui, os_input_output, os_input_output_factory, sample_frames,
sleep_and_quit_events, test_backend_factory,
};
-use ::termion::event::{Event, Key};
+use ::crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use pnet::datalink::DataLinkReceiver;
use std::iter;
@@ -66,11 +66,20 @@ fn pause_by_space() {
// sleep for 1s, then press space, sleep for 2s, then quit
let mut events: Vec<Option<Event>> = iter::repeat(None).take(1).collect();
- events.push(Some(Event::Key(Key::Char(' '))));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Char(' '),
+ })));
events.push(None);
events.push(None);
- events.push(Some(Event::Key(Key::Char(' '))));
- events.push(Some(Event::Key(Key::Ctrl('c'))));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Char(' '),
+ })));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::CONTROL,
+ code: KeyCode::Char('c'),
+ })));
let events = Box::new(KeyboardEvents::new(events));
let os_input = os_input_output_factory(network_frames, None, None, events);
@@ -116,10 +125,16 @@ fn rearranged_by_tab() {
// sleep for 1s, then press tab, sleep for 2s, then quit
let mut events: Vec<Option<Event>> = iter::repeat(None).take(1).collect();
events.push(None);
- events.push(Some(Event::Key(Key::Char('\t'))));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::NONE,
+ code: KeyCode::Tab,
+ })));
events.push(None);
events.push(None);
- events.push(Some(Event::Key(Key::Ctrl('c'))));
+ events.push(Some(Event::Key(KeyEvent {
+ modifiers: KeyModifiers::CONTROL,
+ code: KeyCode::Char('c'),
+ })));
let events = Box::new(KeyboardEvents::new(events));
let os_input = os_input_output_factory(network_frames, None, None, events);
diff --git a/src/tests/fakes/fake_input.rs b/src/tests/fakes/fake_input.rs
index b0f7d19..ac6c246 100644
--- a/src/tests/fakes/fake_input.rs
+++ b/src/tests/fakes/fake_input.rs
@@ -1,11 +1,11 @@
use ::async_trait::async_trait;
+use ::crossterm::event::Event;
use ::ipnetwork::IpNetwork;
use ::pnet::datalink::DataLinkReceiver;
use ::pnet::datalink::NetworkInterface;
use ::std::collections::HashMap;
use ::std::net::{IpAddr, Ipv4Addr, SocketAddr};
use ::std::{thread, time};
-use ::termion::event::Event;
use ::tokio::runtime::Runtime;
use crate::{