use crate::buffer::{AppMode, Buffer, FilterState, FuzzyFilterState, SearchState};
use crate::state::events::{StateChange, StateEvent};
use crate::ui::state::shadow_state::SearchType;
use tracing::{debug, info};
pub trait StateCoordinator {
fn process_event(&self, event: &StateEvent) -> StateChange;
fn apply_change(&mut self, change: StateChange);
fn emit_event(&self, event: StateEvent);
}
impl StateCoordinator for Buffer {
fn process_event(&self, event: &StateEvent) -> StateChange {
match event {
StateEvent::ModeChanged { from, to } => self.process_mode_change(from, to),
StateEvent::SearchStarted { search_type } => self.process_search_start(search_type),
StateEvent::SearchEnded { search_type } => self.process_search_end(search_type),
_ => StateChange::default(),
}
}
fn apply_change(&mut self, change: StateChange) {
debug!("Buffer applying state change: {:?}", change);
if let Some(mode) = change.mode {
self.mode = mode;
}
if change.clear_all_searches {
info!("Buffer: Clearing all search states");
self.search_state = SearchState::default();
self.filter_state = FilterState::default();
self.fuzzy_filter_state = FuzzyFilterState::default();
} else {
if let Some(search) = change.search_state {
self.search_state = search;
}
if let Some(filter) = change.filter_state {
self.filter_state = filter;
}
if let Some(fuzzy) = change.fuzzy_filter_state {
self.fuzzy_filter_state = fuzzy;
}
}
}
fn emit_event(&self, event: StateEvent) {
debug!("Buffer emitting event: {:?}", event);
}
}
impl Buffer {
fn process_mode_change(&self, from: &AppMode, to: &AppMode) -> StateChange {
debug!("Processing mode change: {:?} -> {:?}", from, to);
match (from, to) {
(
AppMode::Search | AppMode::Filter | AppMode::FuzzyFilter | AppMode::ColumnSearch,
AppMode::Results,
) => {
info!("Exiting search mode -> clearing all searches");
StateChange::clear_searches().and(StateChange::mode(AppMode::Results))
}
(AppMode::Results, AppMode::Search) => {
let mut change = StateChange::mode(AppMode::Search);
change.filter_state = Some(FilterState::default());
change.fuzzy_filter_state = Some(FuzzyFilterState::default());
change
}
_ => StateChange::mode(to.clone()),
}
}
fn process_search_start(&self, search_type: &SearchType) -> StateChange {
debug!("Processing search start: {:?}", search_type);
match search_type {
SearchType::Vim => {
let mut change = StateChange::mode(AppMode::Search);
change.filter_state = Some(FilterState::default());
change.fuzzy_filter_state = Some(FuzzyFilterState::default());
change
}
SearchType::Column => StateChange::mode(AppMode::ColumnSearch),
SearchType::Fuzzy => {
let mut change = StateChange::mode(AppMode::FuzzyFilter);
change.search_state = Some(SearchState::default());
change.filter_state = Some(FilterState::default());
change
}
SearchType::Data => {
let mut change = StateChange::mode(AppMode::Filter);
change.search_state = Some(SearchState::default());
change.fuzzy_filter_state = Some(FuzzyFilterState::default());
change
}
}
}
fn process_search_end(&self, search_type: &SearchType) -> StateChange {
info!("Processing search end: {:?}", search_type);
match search_type {
SearchType::Vim => {
let mut change = StateChange::mode(AppMode::Results);
change.search_state = Some(SearchState::default());
change
}
SearchType::Column => StateChange::mode(AppMode::Results),
SearchType::Fuzzy => {
let mut change = StateChange::mode(AppMode::Results);
change.fuzzy_filter_state = Some(FuzzyFilterState::default());
change
}
SearchType::Data => {
let mut change = StateChange::mode(AppMode::Results);
change.filter_state = Some(FilterState::default());
change
}
}
}
}