}
})?;
- 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<FeedId>) }
+
+ let todos = match self.subthread_receiver.recv() {
Err(e) => break 'outer Err(e.into()),
Ok(SubthreadEvent::TermEv(ev)) => {
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 => (),
+ }
}
}
}