sql_cli/state/
coordinator.rs

1//! State coordination trait for Buffer
2
3use crate::buffer::{AppMode, Buffer, FilterState, FuzzyFilterState, SearchState};
4use crate::state::events::{StateChange, StateEvent};
5use crate::ui::state::shadow_state::SearchType;
6use tracing::{debug, info};
7
8/// Trait for coordinating state changes
9pub trait StateCoordinator {
10    /// Process a state event and return changes to apply
11    fn process_event(&self, event: &StateEvent) -> StateChange;
12
13    /// Apply a state change to the buffer
14    fn apply_change(&mut self, change: StateChange);
15
16    /// Emit an event (for notification)
17    fn emit_event(&self, event: StateEvent);
18}
19
20impl StateCoordinator for Buffer {
21    fn process_event(&self, event: &StateEvent) -> StateChange {
22        match event {
23            StateEvent::ModeChanged { from, to } => self.process_mode_change(from, to),
24            StateEvent::SearchStarted { search_type } => self.process_search_start(search_type),
25            StateEvent::SearchEnded { search_type } => self.process_search_end(search_type),
26            _ => StateChange::default(),
27        }
28    }
29
30    fn apply_change(&mut self, change: StateChange) {
31        debug!("Buffer applying state change: {:?}", change);
32
33        if let Some(mode) = change.mode {
34            self.mode = mode;
35        }
36
37        if change.clear_all_searches {
38            info!("Buffer: Clearing all search states");
39            self.search_state = SearchState::default();
40            self.filter_state = FilterState::default();
41            self.fuzzy_filter_state = FuzzyFilterState::default();
42        } else {
43            if let Some(search) = change.search_state {
44                self.search_state = search;
45            }
46            if let Some(filter) = change.filter_state {
47                self.filter_state = filter;
48            }
49            if let Some(fuzzy) = change.fuzzy_filter_state {
50                self.fuzzy_filter_state = fuzzy;
51            }
52        }
53    }
54
55    fn emit_event(&self, event: StateEvent) {
56        // This will be connected to the dispatcher
57        debug!("Buffer emitting event: {:?}", event);
58    }
59}
60
61impl Buffer {
62    /// Process mode change and determine required state changes
63    fn process_mode_change(&self, from: &AppMode, to: &AppMode) -> StateChange {
64        debug!("Processing mode change: {:?} -> {:?}", from, to);
65
66        match (from, to) {
67            // Exiting any search mode to Results
68            (
69                AppMode::Search | AppMode::Filter | AppMode::FuzzyFilter | AppMode::ColumnSearch,
70                AppMode::Results,
71            ) => {
72                info!("Exiting search mode -> clearing all searches");
73                StateChange::clear_searches().and(StateChange::mode(AppMode::Results))
74            }
75
76            // Entering search mode from Results
77            (AppMode::Results, AppMode::Search) => {
78                // Clear other search types
79                let mut change = StateChange::mode(AppMode::Search);
80                change.filter_state = Some(FilterState::default());
81                change.fuzzy_filter_state = Some(FuzzyFilterState::default());
82                change
83            }
84
85            // Default mode change
86            _ => StateChange::mode(to.clone()),
87        }
88    }
89
90    /// Process search start event
91    fn process_search_start(&self, search_type: &SearchType) -> StateChange {
92        debug!("Processing search start: {:?}", search_type);
93
94        match search_type {
95            SearchType::Vim => {
96                let mut change = StateChange::mode(AppMode::Search);
97                // Clear other search types
98                change.filter_state = Some(FilterState::default());
99                change.fuzzy_filter_state = Some(FuzzyFilterState::default());
100                change
101            }
102            SearchType::Column => StateChange::mode(AppMode::ColumnSearch),
103            SearchType::Fuzzy => {
104                let mut change = StateChange::mode(AppMode::FuzzyFilter);
105                // Clear other search types
106                change.search_state = Some(SearchState::default());
107                change.filter_state = Some(FilterState::default());
108                change
109            }
110            SearchType::Data => {
111                let mut change = StateChange::mode(AppMode::Filter);
112                // Clear other search types
113                change.search_state = Some(SearchState::default());
114                change.fuzzy_filter_state = Some(FuzzyFilterState::default());
115                change
116            }
117        }
118    }
119
120    /// Process search end event
121    fn process_search_end(&self, search_type: &SearchType) -> StateChange {
122        info!("Processing search end: {:?}", search_type);
123
124        // Clear the specific search type and return to Results
125        match search_type {
126            SearchType::Vim => {
127                let mut change = StateChange::mode(AppMode::Results);
128                change.search_state = Some(SearchState::default());
129                change
130            }
131            SearchType::Column => StateChange::mode(AppMode::Results),
132            SearchType::Fuzzy => {
133                let mut change = StateChange::mode(AppMode::Results);
134                change.fuzzy_filter_state = Some(FuzzyFilterState::default());
135                change
136            }
137            SearchType::Data => {
138                let mut change = StateChange::mode(AppMode::Results);
139                change.filter_state = Some(FilterState::default());
140                change
141            }
142        }
143    }
144}