Move command parser to clap

This commit is contained in:
Gregor Reitzenstein 2020-11-04 13:07:31 +01:00
parent 925460bd40
commit c62c999349
4 changed files with 37 additions and 18 deletions

View File

@ -26,7 +26,7 @@ smol = "1.2"
signal-hook = "0.1" signal-hook = "0.1"
slog = { version = "2.5", features = ["max_level_trace"] } slog = { version = "2.5", features = ["max_level_debug"] }
libc = "0.2" libc = "0.2"
rsasl = "0.2.3" rsasl = "0.2.3"

View File

@ -11,6 +11,7 @@ use termion::event::Key;
use crate::input::Inputs; use crate::input::Inputs;
use crate::schema::API; use crate::schema::API;
use crate::commands::{CommandParser, Commands};
use slog::{ use slog::{
Logger, Logger,
@ -41,6 +42,7 @@ pub struct Sute<'a, S> {
inputs: Inputs, inputs: Inputs,
api: Option<API>, api: Option<API>,
log: Logger, log: Logger,
cmds: CommandParser<'a>,
drain: Arc<LogDrain<'a>>, drain: Arc<LogDrain<'a>>,
} }
@ -49,18 +51,24 @@ impl<'a, S: Unpin> Sute<'a, S> {
pub fn new(signal: S, log: Logger, drain: Arc<LogDrain<'a>>, api: Option<API>) -> Self { pub fn new(signal: S, log: Logger, drain: Arc<LogDrain<'a>>, api: Option<API>) -> Self {
let inputs = Inputs::new(); let inputs = Inputs::new();
let state = Mutable::new(SuteState::new()); let state = Mutable::new(SuteState::new());
let cmds = CommandParser::new();
Self { state, signal, inputs, api, log, drain, } Self { state, signal, inputs, api, log, cmds, drain, }
} }
fn run_cmd(&mut self, cmdline: String) { fn run_cmd(&mut self, cmdline: String) {
let mut words = cmdline.split_ascii_whitespace(); let mut words = cmdline.split_ascii_whitespace().map(|s| s.to_string());
match words.next() { match self.cmds.parse(words) {
Some("quit") => self.state.lock_mut().running = false, Ok(matches) => {
Some("connect") => { match matches.subcommand() {
self.connect(cmdline) Some(("quit", _)) => self.state.lock_mut().running = false,
Some((s, m)) => info!(self.log, "Got Command {} with params {:?}", s, m),
None => error!(self.log, "No command provided."),
}
}, },
cmd => info!(self.log, "Issues unknown cmd: {:?}", cmd), Err(e) => {
error!(self.log, "{}", e);
}
} }
} }
@ -84,21 +92,25 @@ impl<'a, S: Unpin> Sute<'a, S> {
pub fn handle_key(&mut self, key: Key) { pub fn handle_key(&mut self, key: Key) {
trace!(self.log, "Locking in handle_key"); trace!(self.log, "Locking in handle_key");
let mut state = self.state.lock_mut();
match key { match key {
Key::Char('\n') => { Key::Char('\n') => {
let mut state = self.state.lock_mut();
let cmd = mem::replace(&mut state.cmd_line, String::new()); let cmd = mem::replace(&mut state.cmd_line, String::new());
// drop the mutably borrowed state here so we can mutably re-borrow self afterwards // drop the mutably borrowed state here so we can mutably re-borrow self afterwards
mem::drop(state); mem::drop(state);
self.run_cmd(cmd); self.run_cmd(cmd);
}, },
Key::Char(c) => { Key::Char(c) => {
state.cmd_line.push(c); self.state.lock_mut().cmd_line.push(c);
}, },
Key::Backspace => { Key::Backspace => {
state.cmd_line.pop(); self.state.lock_mut().cmd_line.pop();
}, },
_ => { _ => {
// FIXME: Currently we *must* modify state here otherwise the signal is parked
// indefinitely and the system will never update.
let mut state = self.state.lock_mut();
state.tick += 1;
} }
} }
} }
@ -115,16 +127,17 @@ impl <'a, S: Unpin + Signal<Item=(u16,u16)>> Future for Sute<'a, S> {
if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) { if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) {
self.handle_resize(size); self.handle_resize(size);
} }
match ready!(Pin::new(&mut self.inputs).poll_next(cx)) { match Pin::new(&mut self.inputs).poll_next(cx) {
Some(key) => { Poll::Ready(Some(key)) => {
self.handle_key(key); self.handle_key(key);
}, },
// If the input closes stop the program // If the input closes stop the program
None => { Poll::Ready(None) => {
trace!(self.log, "Locking in impl Future for Sute"); trace!(self.log, "Locking in impl Future for Sute");
self.state.lock_mut().running = false; self.state.lock_mut().running = false;
return Poll::Ready(()); return Poll::Ready(());
}, },
Poll::Pending => {}
} }
Poll::Pending Poll::Pending

View File

@ -5,11 +5,11 @@ use clap::{
Error, Error,
}; };
enum Commands { pub enum Commands {
} }
struct CommandParser<'help> { pub struct CommandParser<'help> {
app: App<'help>, app: App<'help>,
} }
@ -21,7 +21,11 @@ impl<'help> CommandParser<'help> {
.setting(AppSettings::StrictUtf8) .setting(AppSettings::StrictUtf8)
.setting(AppSettings::ColorAlways) .setting(AppSettings::ColorAlways)
.setting(AppSettings::NoBinaryName) .setting(AppSettings::NoBinaryName)
.subcommand(App::new("connect")), .subcommand(App::new("quit"))
.subcommand(App::new("connect"))
.subcommand(App::new("authenticate")
)
,
} }
} }

View File

@ -73,7 +73,8 @@ fn main() -> Result<(), io::Error> {
let mut app_state = app.get_state(); let mut app_state = app.get_state();
let mut ui_state = ui::UIState::new(app_state, drain); let mut ui_state = ui::UIState::new(app_state, drain);
let mut stream = app.signal().to_stream();
let signal = app.signal();
let ui_future = async move { let ui_future = async move {
let stdout = io::stdout().into_raw_mode()?; let stdout = io::stdout().into_raw_mode()?;
@ -89,6 +90,7 @@ fn main() -> Result<(), io::Error> {
} }
terminal.draw(|f| ui::draw_ui(f, &mut ui_state)); terminal.draw(|f| ui::draw_ui(f, &mut ui_state));
let mut stream = signal.to_stream();
loop { loop {
if let Some(mut state) = stream.next().await { if let Some(mut state) = stream.next().await {
if !state.running { if !state.running {