chiark / gitweb /
Clean up huge piece of duplicated logic in Tui.
authorSimon Tatham <anakin@pobox.com>
Sun, 7 Jan 2024 08:37:40 +0000 (08:37 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 7 Jan 2024 08:37:40 +0000 (08:37 +0000)
Adding the refresh key to it was more than I could bear.

src/tui.rs

index 87ad0627b8001432d3bfe31879c4559020bb4f12..7f24fbe172e044516b01803f6b14419f2ef6a902 100644 (file)
@@ -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<FeedId>) }
+
+            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 => (),
+                }
             }
         }
     }