diff --git a/Cargo.lock b/Cargo.lock index eb83799..52f58bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1117,6 +1117,7 @@ dependencies = [ "pikl-core", "ratatui", "tokio", + "tracing", ] [[package]] diff --git a/crates/pikl-core/src/model/traits.rs b/crates/pikl-core/src/model/traits.rs index f8a7f53..866a1e3 100644 --- a/crates/pikl-core/src/model/traits.rs +++ b/crates/pikl-core/src/model/traits.rs @@ -32,9 +32,6 @@ pub trait Menu: Send + 'static { /// position in the filtered results. fn filtered_label(&self, filtered_index: usize) -> Option<&str>; - /// Add raw values from streaming input or AddItems actions. - fn add_raw(&mut self, values: Vec); - /// Get the JSON value of a filtered item for output. /// Returns a reference to the stored value. fn serialize_filtered(&self, filtered_index: usize) -> Option<&serde_json::Value>; @@ -44,14 +41,6 @@ pub trait Menu: Send + 'static { /// for output and hook events. fn original_index(&self, filtered_index: usize) -> Option; - /// Replace all items with a new set of values. Used by - /// handler hook `replace_items` responses. - fn replace_all(&mut self, values: Vec); - - /// Remove items at the given original indices. Used by - /// handler hook `remove_items` responses. - fn remove_by_indices(&mut self, indices: Vec); - /// Get the formatted display text for a filtered item, /// if a format template is configured. Returns None if /// no template is set, in which case the raw label is @@ -73,3 +62,20 @@ pub trait Menu: Send + 'static { .collect() } } + +/// Extension of [`Menu`] with mutation methods. Required by +/// [`MenuRunner`] which needs to add, replace, and remove +/// items. Embedders that only need read-only access can +/// depend on `Menu` alone. +pub trait MutableMenu: Menu { + /// Add raw values from streaming input or AddItems actions. + fn add_raw(&mut self, values: Vec); + + /// Replace all items with a new set of values. Used by + /// handler hook `replace_items` responses. + fn replace_all(&mut self, values: Vec); + + /// Remove items at the given original indices. Used by + /// handler hook `remove_items` responses. + fn remove_by_indices(&mut self, indices: Vec); +} diff --git a/crates/pikl-core/src/runtime/json_menu.rs b/crates/pikl-core/src/runtime/json_menu.rs index 6a6812f..f118a95 100644 --- a/crates/pikl-core/src/runtime/json_menu.rs +++ b/crates/pikl-core/src/runtime/json_menu.rs @@ -5,7 +5,7 @@ use crate::filter::Filter; use crate::format::FormatTemplate; use crate::item::Item; -use crate::model::traits::Menu; +use crate::model::traits::{Menu, MutableMenu}; use crate::pipeline::FilterPipeline; /// A menu backed by a flat list of JSON items. Handles @@ -120,16 +120,6 @@ impl Menu for JsonMenu { .map(|idx| self.items[idx].label()) } - fn add_raw(&mut self, values: Vec) { - for value in values { - let idx = self.items.len(); - let item = Item::new(value, &self.label_key); - let text = self.extract_filter_text(&item); - self.filter.push_with_value(idx, &text, &item.value); - self.items.push(item); - } - } - fn serialize_filtered(&self, filtered_index: usize) -> Option<&serde_json::Value> { self.filter .matched_index(filtered_index) @@ -140,6 +130,24 @@ impl Menu for JsonMenu { self.filter.matched_index(filtered_index) } + fn formatted_label(&self, filtered_index: usize) -> Option { + let template = self.format_template.as_ref()?; + let orig_idx = self.filter.matched_index(filtered_index)?; + Some(template.render(&self.items[orig_idx].value)) + } +} + +impl MutableMenu for JsonMenu { + fn add_raw(&mut self, values: Vec) { + for value in values { + let idx = self.items.len(); + let item = Item::new(value, &self.label_key); + let text = self.extract_filter_text(&item); + self.filter.push_with_value(idx, &text, &item.value); + self.items.push(item); + } + } + fn replace_all(&mut self, values: Vec) { self.items = values .into_iter() @@ -161,10 +169,4 @@ impl Menu for JsonMenu { } self.rebuild_pipeline(); } - - fn formatted_label(&self, filtered_index: usize) -> Option { - let template = self.format_template.as_ref()?; - let orig_idx = self.filter.matched_index(filtered_index)?; - Some(template.render(&self.items[orig_idx].value)) - } } diff --git a/crates/pikl-tui/Cargo.toml b/crates/pikl-tui/Cargo.toml index 5c763f5..dd09a39 100644 --- a/crates/pikl-tui/Cargo.toml +++ b/crates/pikl-tui/Cargo.toml @@ -14,3 +14,4 @@ ratatui = "0.30" crossterm = { version = "0.29", features = ["event-stream"] } tokio = { version = "1", features = ["sync", "macros", "rt"] } futures = "0.3" +tracing = "0.1"