refactor: Eliminate unnecessary empty Vec constructions.

This commit is contained in:
2026-03-14 11:43:48 -04:00
parent 0ebb5e79dd
commit e89c6cb16f
7 changed files with 40 additions and 49 deletions

View File

@@ -11,7 +11,7 @@ use crate::debounce::{hook_response_to_action, DebouncedDispatcher};
use crate::error::PiklError;
use crate::event::{Action, MenuEvent, MenuResult, Mode, ViewState, VisibleItem};
use crate::hook::{HookEvent, HookHandler};
use crate::model::traits::Menu;
use crate::model::traits::MutableMenu;
use crate::navigation::Viewport;
use serde_json::Value;
@@ -37,7 +37,7 @@ pub enum ActionOutcome {
/// drives it with an action/event channel loop. Create one,
/// grab the action sender and event subscriber, then call
/// [`MenuRunner::run`] to start the event loop.
pub struct MenuRunner<M: Menu> {
pub struct MenuRunner<M: MutableMenu> {
menu: M,
viewport: Viewport,
filter_text: Arc<str>,
@@ -46,9 +46,10 @@ pub struct MenuRunner<M: Menu> {
event_tx: broadcast::Sender<MenuEvent>,
dispatcher: Option<DebouncedDispatcher>,
previous_cursor: Option<usize>,
generation: u64,
}
impl<M: Menu> MenuRunner<M> {
impl<M: MutableMenu> MenuRunner<M> {
/// Create a menu runner wrapping the given menu backend.
/// Returns the runner and an action sender. Call
/// [`subscribe`](Self::subscribe) to get an event handle,
@@ -69,6 +70,7 @@ impl<M: Menu> MenuRunner<M> {
event_tx,
dispatcher: None,
previous_cursor: None,
generation: 0,
};
(runner, action_tx)
}
@@ -105,7 +107,8 @@ impl<M: Menu> MenuRunner<M> {
/// Build a [`ViewState`] snapshot from the current filter
/// results and viewport position.
fn build_view_state(&self) -> ViewState {
fn build_view_state(&mut self) -> ViewState {
self.generation += 1;
let range = self.viewport.visible_range();
let visible_items: Vec<VisibleItem> = range
.clone()
@@ -134,14 +137,14 @@ impl<M: Menu> MenuRunner<M> {
total_items: self.menu.total(),
total_filtered: self.menu.filtered_count(),
mode: self.mode,
generation: self.generation,
}
}
/// Send the current view state to all subscribers.
fn broadcast_state(&self) {
let _ = self
.event_tx
.send(MenuEvent::StateChanged(self.build_view_state()));
fn broadcast_state(&mut self) {
let vs = self.build_view_state();
let _ = self.event_tx.send(MenuEvent::StateChanged(vs));
}
/// Emit a hook event through the dispatcher, if one is set.
@@ -390,6 +393,7 @@ mod tests {
use super::*;
use crate::event::MenuEvent;
use crate::item::Item;
use crate::model::traits::Menu;
use crate::runtime::json_menu::JsonMenu;
fn test_menu() -> (MenuRunner<JsonMenu>, mpsc::Sender<Action>) {
@@ -1099,16 +1103,16 @@ mod tests {
#[tokio::test]
async fn hook_events_fire_on_lifecycle() {
use crate::hook::{HookEvent, HookEventKind, HookHandler, HookResponse};
use crate::hook::{HookEvent, HookEventKind, HookHandler};
use std::sync::Mutex;
struct Recorder(Mutex<Vec<HookEventKind>>);
impl HookHandler for Recorder {
fn handle(&self, event: HookEvent) -> Result<Vec<HookResponse>, PiklError> {
fn handle(&self, event: HookEvent) -> Result<(), PiklError> {
if let Ok(mut v) = self.0.lock() {
v.push(event.kind());
}
Ok(vec![])
Ok(())
}
}