sql_cli/debug/
buffer_debug.rs1use crate::buffer::BufferAPI;
2use crate::debug::debug_trace::{DebugSection, DebugSectionBuilder, DebugTrace, Priority};
3use std::sync::Arc;
4
5pub struct BufferDebugProvider {
7 buffer: Arc<dyn BufferAPI>,
8}
9
10impl BufferDebugProvider {
11 pub fn new(buffer: Arc<dyn BufferAPI>) -> Self {
12 Self { buffer }
13 }
14}
15
16impl DebugTrace for BufferDebugProvider {
17 fn name(&self) -> &str {
18 "Buffer"
19 }
20
21 fn debug_sections(&self) -> Vec<DebugSection> {
22 let mut builder = DebugSectionBuilder::new();
23
24 builder.add_section("BUFFER STATE", "", Priority::BUFFER);
26
27 builder.add_field("Buffer Name", self.buffer.get_name());
29 builder.add_field("Current Mode", format!("{:?}", self.buffer.get_mode()));
30
31 let input_text = self.buffer.get_input_text();
33 builder.add_field(
34 "Input Text",
35 if input_text.is_empty() {
36 "(empty)".to_string()
37 } else {
38 format!("'{}' ({} chars)", input_text, input_text.len())
39 },
40 );
41
42 if let Some(selected_row) = self.buffer.get_selected_row() {
44 builder.add_field("Selected Row", selected_row);
45 } else {
46 builder.add_field("Selected Row", "None");
47 }
48 builder.add_field("Current Column", self.buffer.get_current_column());
49
50 let last_query = self.buffer.get_last_query();
52 if !last_query.is_empty() {
53 builder.add_field(
54 "Last Query",
55 format!(
56 "'{}' ({} chars)",
57 if last_query.len() > 50 {
58 format!("{}...", &last_query[..50])
59 } else {
60 last_query.clone()
61 },
62 last_query.len()
63 ),
64 );
65 }
66
67 if let Some(dataview) = self.buffer.get_dataview() {
69 builder.add_field("Has DataView", "Yes");
70 builder.add_field("Result Rows", dataview.row_count());
71 builder.add_field("Result Columns", dataview.column_count());
72 } else {
73 builder.add_field("Has DataView", "No");
74 }
75
76 let (scroll_row, scroll_col) = self.buffer.get_scroll_offset();
78 builder.add_field(
79 "Scroll Offset",
80 format!("row={}, col={}", scroll_row, scroll_col),
81 );
82
83 builder.add_field(
85 "Viewport Lock",
86 if self.buffer.is_viewport_lock() {
87 if let Some(lock_row) = self.buffer.get_viewport_lock_row() {
88 format!("Locked at row {}", lock_row)
89 } else {
90 "Locked (no specific row)".to_string()
91 }
92 } else {
93 "Unlocked".to_string()
94 },
95 );
96
97 let filter_pattern = self.buffer.get_filter_pattern();
99 if !filter_pattern.is_empty() {
100 builder.add_field("Filter Pattern", format!("'{}'", filter_pattern));
101 builder.add_field("Filter Active", self.buffer.is_filter_active());
102 }
103
104 let status_msg = self.buffer.get_status_message();
106 if !status_msg.is_empty() {
107 builder.add_field("Status Message", status_msg);
108 }
109
110 builder.build()
111 }
112
113 fn debug_summary(&self) -> Option<String> {
114 let mode = self.buffer.get_mode();
115 let has_data = self.buffer.get_dataview().is_some();
116 let input_len = self.buffer.get_input_text().len();
117
118 Some(format!(
119 "Mode: {:?}, Input: {} chars, Data: {}",
120 mode,
121 input_len,
122 if has_data { "Yes" } else { "No" }
123 ))
124 }
125
126 fn is_active(&self) -> bool {
127 true
128 }
129}
130
131pub struct BufferManagerDebugProvider {
133 buffers: Vec<Arc<dyn BufferAPI>>,
134 current_index: usize,
135}
136
137impl BufferManagerDebugProvider {
138 pub fn new(buffers: Vec<Arc<dyn BufferAPI>>, current_index: usize) -> Self {
139 Self {
140 buffers,
141 current_index,
142 }
143 }
144}
145
146impl DebugTrace for BufferManagerDebugProvider {
147 fn name(&self) -> &str {
148 "BufferManager"
149 }
150
151 fn debug_sections(&self) -> Vec<DebugSection> {
152 let mut builder = DebugSectionBuilder::new();
153
154 builder.add_section("BUFFER MANAGER", "", Priority::BUFFER - 10);
155
156 builder.add_field("Total Buffers", self.buffers.len());
157 builder.add_field("Current Buffer Index", self.current_index);
158
159 if let Some(current) = self.buffers.get(self.current_index) {
160 builder.add_field("Current Buffer Name", current.get_name());
161 }
162
163 builder.add_line("");
164 builder.add_line("All Buffers:");
165 for (idx, buffer) in self.buffers.iter().enumerate() {
166 let marker = if idx == self.current_index {
167 " * "
168 } else {
169 " "
170 };
171 let mode = buffer.get_mode();
172 let has_data = buffer.get_dataview().is_some();
173 builder.add_line(format!(
174 "{} [{}] {} - Mode: {:?}, Data: {}",
175 marker,
176 idx,
177 buffer.get_name(),
178 mode,
179 if has_data { "Yes" } else { "No" }
180 ));
181 }
182
183 builder.build()
184 }
185
186 fn debug_summary(&self) -> Option<String> {
187 Some(format!(
188 "{} buffers, current: #{} ({})",
189 self.buffers.len(),
190 self.current_index,
191 self.buffers
192 .get(self.current_index)
193 .map(|b| b.get_name())
194 .unwrap_or_else(|| "none".to_string())
195 ))
196 }
197}