Swapped out termion for crossterm

This commit is contained in:
2025-09-20 22:48:12 +02:00
parent e4c4a7f14a
commit 37f15bf187
4 changed files with 343 additions and 58 deletions

View File

@@ -1,32 +1,46 @@
use std::io::{Error, ErrorKind, Write};
use std::time::Duration;
use crossterm::event::{Event, KeyCode, KeyModifiers};
use serial2::SerialPort;
use termion::raw::IntoRawMode;
use termion::event::Key;
use termion::input::TermRead;
struct RawMode {}
impl RawMode {
fn init() -> Result<Self, Error> {
crossterm::terminal::enable_raw_mode()?;
Ok(Self {})
}
}
impl Drop for RawMode {
fn drop(&mut self) {
let _ = crossterm::terminal::disable_raw_mode();
}
}
pub struct Monitor {
hooks: Vec<(Key, &'static str)>
hooks: Vec<(KeyCode, KeyModifiers, &'static str)>
}
impl Monitor {
pub fn new() -> Self {
let mut hooks = Vec::new();
hooks.push((Key::Ctrl('c'), "Exit monitor"));
hooks.push((Key::Ctrl('r'), "Reboot target"));
hooks.push((KeyCode::Char('c'), KeyModifiers::CONTROL, "Exit monitor"));
hooks.push((KeyCode::Char('r'), KeyModifiers::CONTROL, "Reboot target"));
Self { hooks }
}
pub fn add_hook(&mut self, key: Key, desc: &'static str) -> &mut Self {
self.hooks.push((key, desc));
self
pub fn add_hook(&mut self, key: KeyCode, mods: KeyModifiers, desc: &'static str) -> usize {
let idx = self.hooks.len();
self.hooks.push((key, mods, desc));
idx
}
pub fn run(&mut self, port: &mut SerialPort) -> Result<Key, Error> {
pub fn run(&mut self, port: &mut SerialPort) -> Result<usize, Error> {
port.set_dtr(true)?;
port.set_rts(true)?;
std::thread::sleep(Duration::from_millis(100));
@@ -36,10 +50,10 @@ impl Monitor {
println!();
println!("Monitor controls:");
for (key, desc) in &self.hooks {
let key = match key {
Key::Char(c) => format!("{}", c.to_uppercase()),
Key::Ctrl(c) => format!("Ctrl+{}", c.to_uppercase()),
for (key, mods, desc) in &self.hooks {
let key = match (key, *mods) {
(KeyCode::Char(c), KeyModifiers::NONE) => format!("{}", c.to_uppercase()),
(KeyCode::Char(c), KeyModifiers::CONTROL) => format!("Ctrl+{}", c.to_uppercase()),
key => format!("{:?}", key)
};
@@ -48,9 +62,8 @@ impl Monitor {
println!();
let mut stdout = std::io::stdout().into_raw_mode().unwrap();
let mut stdin = termion::async_stdin().keys();
let _raw = RawMode::init()?;
let mut stdout = std::io::stdout();
'main: loop {
let mut buf = [0u8; 1];
@@ -70,8 +83,13 @@ impl Monitor {
Err(err)?
}
if let Some(Ok(key)) = stdin.next() {
if let Key::Ctrl('r') = key {
if crossterm::event::poll(Duration::ZERO)? {
let (key, mods) = match crossterm::event::read()? {
Event::Key(ev) => (ev.code, ev.modifiers),
_ => continue
};
if key == KeyCode::Char('r') && mods == KeyModifiers::CONTROL {
stdout.write_all(b"\r\n*** Reboot ***\r\n")?;
port.set_dtr(true)?;
port.set_rts(true)?;
@@ -81,10 +99,10 @@ impl Monitor {
continue
}
for (hook_key, _) in &self.hooks {
if hook_key == &key {
for (idx, (hook_key, hook_mods, _)) in self.hooks.iter().enumerate() {
if hook_key == &key && hook_mods == &mods {
stdout.write_all(b"\r\n")?;
break 'main Ok(key)
break 'main Ok(idx)
}
}
}