From 8488b749ccfda5a142bf36ed98e262fe1daa5aca Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 7 Jan 2024 08:37:40 +0000 Subject: [PATCH] Clean up huge piece of duplicated logic in Tui. Adding the refresh key to it was more than I could bear. --- src/tui.rs | 89 ++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/src/tui.rs b/src/tui.rs index 87ad062..7f24fbe 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -375,7 +375,19 @@ impl Tui { } })?; - match self.subthread_receiver.recv() { + // One physical keypress can break down into multiple + // things we treat as logical keypresses. So we must do an + // awkward two-step handling here where we first process + // the incoming event into a vector of things to do, and + // then loop over that vector handling the PhysicalActions + // that come back. + // + // Repeating the whole match on PhysicalAction branches in + // the TermEv and StreamEv branches would be worse! + + enum Todo { Keypress(OurKey), Stream(HashSet) } + + let todos = match self.subthread_receiver.recv() { Err(e) => break 'outer Err(e.into()), Ok(SubthreadEvent::TermEv(ev)) => { @@ -383,64 +395,47 @@ impl Tui { Event::Key(key) => { if key.kind == KeyEventKind::Press { state.new_event(); - for ourkey in Self::translate_keypress(key) { - match state.handle_keypress( - ourkey, &mut self.client) { - PhysicalAction::Beep => { - Self::beep()? - } - - PhysicalAction::Exit => { - break 'outer Ok(()); - } - - PhysicalAction::Refresh => { - self.terminal.clear()?; - } - - PhysicalAction::Error(err) => { - break 'outer Err(err); - } - - PhysicalAction::Nothing => (), - } - } + Self::translate_keypress(key).into_iter() + .map(|key| Todo::Keypress(key)) + .collect() + } else { + Vec::new() } } - _ => (), + _ => Vec::new(), } } Ok(SubthreadEvent::StreamEv(update)) => { match self.client.process_stream_update(update) { Ok(feeds_updated) => { - match state.handle_feed_updates(feeds_updated, - &mut self.client) { - PhysicalAction::Beep => { - Self::beep()? - } - - PhysicalAction::Exit => { - break 'outer Ok(()); - } - - PhysicalAction::Refresh => { - self.terminal.clear()?; - } - - PhysicalAction::Error(err) => { - break 'outer Err(err); - } - - PhysicalAction::Nothing => (), - } + vec! { Todo::Stream(feeds_updated) } } // FIXME: errors here should go in the Error Log - _ => (), + _ => Vec::new(), } } - Ok(SubthreadEvent::LDBCheckpointTimer) => - state.checkpoint_ldb(), + Ok(SubthreadEvent::LDBCheckpointTimer) => { + state.checkpoint_ldb(); + Vec::new() + } + }; + + for todo in todos { + let physact = match todo { + Todo::Keypress(ourkey) => state.handle_keypress( + ourkey, &mut self.client), + Todo::Stream(feeds_updated) => state.handle_feed_updates( + feeds_updated, &mut self.client), + }; + + match physact { + PhysicalAction::Beep => Self::beep()?, + PhysicalAction::Exit => break 'outer Ok(()), + PhysicalAction::Refresh => self.terminal.clear()?, + PhysicalAction::Error(err) => break 'outer Err(err), + PhysicalAction::Nothing => (), + } } } } -- 2.30.2