sql_cli/ui/behaviors/
status_behavior.rs

1// Status and error message handling behavior
2// Manages all status bar updates and error display
3
4use anyhow::Result;
5
6/// Trait for managing status and error messages in the UI
7pub trait StatusBehavior {
8    // Required methods - provide access to TUI internals
9    fn buffer_mut(&mut self) -> &mut dyn crate::buffer::BufferAPI;
10
11    /// Set a status message
12    fn set_status(&mut self, message: impl Into<String>) {
13        let msg = message.into();
14        tracing::debug!("Status: {}", msg);
15        self.buffer_mut().set_status_message(msg);
16    }
17
18    /// Set an error message with context
19    fn set_error(&mut self, context: &str, error: impl std::fmt::Display) {
20        let msg = format!("{}: {}", context, error);
21        tracing::error!("Error status: {}", msg);
22        self.buffer_mut().set_status_message(msg);
23    }
24
25    /// Set a success message
26    fn set_success(&mut self, message: impl Into<String>) {
27        let msg = message.into();
28        tracing::info!("Success: {}", msg);
29        self.buffer_mut().set_status_message(msg);
30    }
31
32    /// Clear the current status message
33    fn clear_status(&mut self) {
34        self.buffer_mut().set_status_message(String::new());
35    }
36
37    /// Set a temporary status message that auto-clears after a duration
38    fn set_temporary_status(&mut self, message: impl Into<String>, _duration_ms: u64) {
39        // For now, just set the status - timer functionality can be added later
40        self.set_status(message);
41    }
42
43    /// Format and set a query execution status
44    fn set_query_status(&mut self, rows: usize, columns: usize, elapsed_ms: u64) {
45        self.set_status(format!(
46            "Query executed: {} rows, {} columns ({} ms)",
47            rows, columns, elapsed_ms
48        ));
49    }
50
51    /// Set a search status with match count
52    fn set_search_status(&mut self, pattern: &str, current: usize, total: usize) {
53        if total == 0 {
54            self.set_status(format!("/{} - no matches", pattern));
55        } else {
56            self.set_status(format!("Match {}/{} for '{}'", current, total, pattern));
57        }
58    }
59
60    /// Set a filter status
61    fn set_filter_status(&mut self, active: bool, matches: usize) {
62        if active {
63            self.set_status(format!("Filter active: {} matches", matches));
64        } else {
65            self.set_status("Filter cleared");
66        }
67    }
68
69    /// Set a column operation status
70    fn set_column_status(&mut self, operation: &str, column_name: &str) {
71        self.set_status(format!("{}: {}", operation, column_name));
72    }
73
74    /// Set a navigation status
75    fn set_navigation_status(&mut self, description: &str) {
76        self.set_status(description);
77    }
78
79    /// Set a mode change status
80    fn set_mode_status(&mut self, new_mode: &str) {
81        self.set_status(format!("{} mode", new_mode));
82    }
83
84    /// Set a yank operation status
85    fn set_yank_status(&mut self, target: &str, size: usize) {
86        self.set_status(format!("Yanked {} ({} items)", target, size));
87    }
88
89    /// Set a chord mode status
90    fn set_chord_status(&mut self, chord: &str, completions: &[String]) {
91        if completions.is_empty() {
92            self.set_status(format!("Chord: {} (no completions)", chord));
93        } else {
94            let completion_str = completions.join(", ");
95            self.set_status(format!("Chord: {} - available: {}", chord, completion_str));
96        }
97    }
98
99    /// Set a history search status
100    fn set_history_status(&mut self, matches: usize) {
101        self.set_status(format!("History search: {} matches", matches));
102    }
103
104    /// Handle status from a result type
105    fn handle_result_status<T>(
106        &mut self,
107        result: Result<T>,
108        success_msg: &str,
109        error_context: &str,
110    ) -> Option<T> {
111        match result {
112            Ok(value) => {
113                self.set_success(success_msg);
114                Some(value)
115            }
116            Err(e) => {
117                self.set_error(error_context, e);
118                None
119            }
120        }
121    }
122}