use std::io::Error; use std::time::Duration; use serial2::SerialPort; use termion::raw::IntoRawMode; use termion::event::Key; use termion::input::TermRead; pub struct Monitor { hooks: Vec<(Key, &'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")); Self { hooks } } pub fn add_hook(&mut self, key: Key, desc: &'static str) { self.hooks.push((key, desc)); } pub fn run(&mut self, port: &mut SerialPort) -> Result { port.set_dtr(true)?; port.set_rts(true)?; std::thread::sleep(Duration::from_millis(100)); port.set_dtr(false)?; port.set_rts(false)?; 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()), key => format!("{:?}", key) }; println!(" {} - {}", key, desc); } println!(); let mut _stdout = std::io::stdout().into_raw_mode().unwrap(); let mut stdin = termion::async_stdin().keys(); 'main: loop { if let Some(Ok(key)) = stdin.next() { if let Key::Ctrl('r') = key { port.set_dtr(true)?; port.set_rts(true)?; std::thread::sleep(Duration::from_millis(10)); port.set_dtr(false)?; port.set_rts(false)?; continue } for (hook_key, _) in &self.hooks { if hook_key == &key { break 'main Ok(key) } } println!("{:?}\r", key); } else { std::thread::sleep(Duration::from_millis(100)); } } } }