sql_cli/ui/behaviors/
status_behavior.rs1use anyhow::Result;
5
6pub trait StatusBehavior {
8 fn buffer_mut(&mut self) -> &mut dyn crate::buffer::BufferAPI;
10
11 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 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 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 fn clear_status(&mut self) {
34 self.buffer_mut().set_status_message(String::new());
35 }
36
37 fn set_temporary_status(&mut self, message: impl Into<String>, _duration_ms: u64) {
39 self.set_status(message);
41 }
42
43 fn set_query_status(&mut self, rows: usize, columns: usize, elapsed_ms: u64) {
45 self.set_status(format!(
46 "Query executed: {rows} rows, {columns} columns ({elapsed_ms} ms)"
47 ));
48 }
49
50 fn set_search_status(&mut self, pattern: &str, current: usize, total: usize) {
52 if total == 0 {
53 self.set_status(format!("/{pattern} - no matches"));
54 } else {
55 self.set_status(format!("Match {current}/{total} for '{pattern}'"));
56 }
57 }
58
59 fn set_filter_status(&mut self, active: bool, matches: usize) {
61 if active {
62 self.set_status(format!("Filter active: {matches} matches"));
63 } else {
64 self.set_status("Filter cleared");
65 }
66 }
67
68 fn set_column_status(&mut self, operation: &str, column_name: &str) {
70 self.set_status(format!("{operation}: {column_name}"));
71 }
72
73 fn set_navigation_status(&mut self, description: &str) {
75 self.set_status(description);
76 }
77
78 fn set_mode_status(&mut self, new_mode: &str) {
80 self.set_status(format!("{new_mode} mode"));
81 }
82
83 fn set_yank_status(&mut self, target: &str, size: usize) {
85 self.set_status(format!("Yanked {target} ({size} items)"));
86 }
87
88 fn set_chord_status(&mut self, chord: &str, completions: &[String]) {
90 if completions.is_empty() {
91 self.set_status(format!("Chord: {chord} (no completions)"));
92 } else {
93 let completion_str = completions.join(", ");
94 self.set_status(format!("Chord: {chord} - available: {completion_str}"));
95 }
96 }
97
98 fn set_history_status(&mut self, matches: usize) {
100 self.set_status(format!("History search: {matches} matches"));
101 }
102
103 fn handle_result_status<T>(
105 &mut self,
106 result: Result<T>,
107 success_msg: &str,
108 error_context: &str,
109 ) -> Option<T> {
110 match result {
111 Ok(value) => {
112 self.set_success(success_msg);
113 Some(value)
114 }
115 Err(e) => {
116 self.set_error(error_context, e);
117 None
118 }
119 }
120 }
121}