sql_cli/debug/
dataview_debug.rs1use crate::data::data_view::{DataView, SortOrder};
2use crate::debug::debug_trace::{DebugSection, DebugSectionBuilder, DebugTrace, Priority};
3use std::sync::Arc;
4
5pub struct DataViewDebugProvider {
7 dataview: Arc<DataView>,
8}
9
10impl DataViewDebugProvider {
11 #[must_use]
12 pub fn new(dataview: Arc<DataView>) -> Self {
13 Self { dataview }
14 }
15}
16
17impl DebugTrace for DataViewDebugProvider {
18 fn name(&self) -> &'static str {
19 "DataView"
20 }
21
22 fn debug_sections(&self) -> Vec<DebugSection> {
23 let mut builder = DebugSectionBuilder::new();
24
25 builder.add_section("DATAVIEW STATE", "", Priority::DATAVIEW);
27
28 builder.add_field("Visible Rows", self.dataview.row_count());
30 builder.add_field("Visible Columns", self.dataview.column_count());
31 builder.add_field("Source Rows", self.dataview.source().row_count());
32 builder.add_field("Source Columns", self.dataview.source().column_count());
33
34 builder.add_line("");
36 builder.add_line(self.dataview.get_column_debug_info());
37
38 let visible_columns = self.dataview.column_names();
40 let column_mappings = self.dataview.get_column_index_mapping();
41 builder.add_line(format!(
42 "\nVisible Columns ({}) with Index Mapping:",
43 visible_columns.len()
44 ));
45 for (visible_idx, col_name, datatable_idx) in &column_mappings {
46 builder.add_line(format!(
47 " V[{visible_idx:3}] → DT[{datatable_idx:3}] : {col_name}"
48 ));
49 }
50
51 builder.add_line("\n--- Internal State ---");
53 let visible_indices = self.dataview.get_visible_column_indices();
54 builder.add_line(format!("visible_columns array: {visible_indices:?}"));
55
56 let pinned_names = self.dataview.get_pinned_column_names();
58 if pinned_names.is_empty() {
59 builder.add_line("Pinned Columns: None");
60 } else {
61 builder.add_line(format!("\nPinned Columns ({}):", pinned_names.len()));
62 for (idx, name) in pinned_names.iter().enumerate() {
63 let source_idx = self.dataview.source().get_column_index(name).unwrap_or(999);
64 builder.add_line(format!(" [{idx}] {name} (source_idx: {source_idx})"));
65 }
66 }
67
68 let sort_state = self.dataview.get_sort_state();
70 match sort_state.order {
71 SortOrder::None => {
72 builder.add_line("Sort State: None");
73 }
74 SortOrder::Ascending => {
75 if let Some(col_idx) = sort_state.column {
76 let col_name = visible_columns
77 .get(col_idx)
78 .map_or("unknown", std::string::String::as_str);
79 builder.add_line(format!(
80 "Sort State: Column {col_idx} ('{col_name}') Ascending ↑"
81 ));
82 } else {
83 builder.add_line("Sort State: Ascending (no column)");
84 }
85 }
86 SortOrder::Descending => {
87 if let Some(col_idx) = sort_state.column {
88 let col_name = visible_columns
89 .get(col_idx)
90 .map_or("unknown", std::string::String::as_str);
91 builder.add_line(format!(
92 "Sort State: Column {col_idx} ('{col_name}') Descending ↓"
93 ));
94 } else {
95 builder.add_line("Sort State: Descending (no column)");
96 }
97 }
98 }
99
100 if let Some(filter) = self.dataview.get_filter_pattern() {
102 builder.add_line(format!("\nText Filter Active: '{filter}'"));
103 }
104 if let Some(fuzzy) = self.dataview.get_fuzzy_filter_pattern() {
105 builder.add_line(format!("Fuzzy Filter Active: '{fuzzy}'"));
106 }
107 if self.dataview.has_column_search() {
108 if let Some(pattern) = self.dataview.column_search_pattern() {
109 builder.add_line(format!("Column Search Active: '{pattern}'"));
110 let matches = self.dataview.get_matching_columns();
111 builder.add_line(format!(" {} matches found", matches.len()));
112 }
113 }
114
115 let original_columns = self.dataview.source().column_names();
117 if visible_columns == original_columns {
118 builder.add_line("\nColumn Order Changed: NO");
119 } else {
120 builder.add_line("\nColumn Order Changed: YES");
121
122 let hidden: Vec<String> = original_columns
124 .iter()
125 .filter(|col| !visible_columns.contains(col))
126 .cloned()
127 .collect();
128 if !hidden.is_empty() {
129 builder.add_line(format!("Hidden Columns ({}):", hidden.len()));
130 for col in hidden {
131 builder.add_line(format!(" - {col}"));
132 }
133 }
134 }
135
136 builder.build()
137 }
138
139 fn debug_summary(&self) -> Option<String> {
140 let rows = self.dataview.row_count();
141 let cols = self.dataview.column_count();
142 let pinned = self.dataview.get_pinned_columns().len();
143 let filtered = self.dataview.has_filter();
144
145 let mut summary = format!("{rows}x{cols} view");
146 if pinned > 0 {
147 summary.push_str(&format!(", {pinned} pinned"));
148 }
149 if filtered {
150 summary.push_str(", filtered");
151 }
152
153 Some(summary)
154 }
155
156 fn is_active(&self) -> bool {
157 true
158 }
159}