1use std::fmt::Debug;
7use std::hash::Hash;
8
9#[derive(Debug, Clone)]
11pub enum FilterSpec {
12 WhereClause(String),
14 FuzzySearch(String),
16 ColumnFilter { column: usize, pattern: String },
18 Custom(String),
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum SortOrder {
25 Ascending,
26 Descending,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
31pub enum DataType {
32 Text,
33 Integer,
34 Float,
35 Date,
36 Boolean,
37 Json,
38 Mixed,
39 Unknown,
40}
41
42#[derive(Debug, Clone)]
44pub struct ColumnStats {
45 pub null_count: usize,
46 pub unique_count: usize,
47 pub min_value: Option<String>,
48 pub max_value: Option<String>,
49 pub mean_value: Option<f64>,
50}
51
52pub trait DataProvider: Send + Sync + Debug {
57 fn get_row(&self, index: usize) -> Option<Vec<String>>;
60
61 fn get_column_names(&self) -> Vec<String>;
63
64 fn get_row_count(&self) -> usize;
66
67 fn get_column_count(&self) -> usize;
69
70 fn get_visible_rows(&self, start: usize, count: usize) -> Vec<Vec<String>> {
73 let mut rows = Vec::new();
74 let end = (start + count).min(self.get_row_count());
75
76 for i in start..end {
77 if let Some(row) = self.get_row(i) {
78 rows.push(row);
79 }
80 }
81
82 rows
83 }
84
85 fn get_column_widths(&self) -> Vec<usize> {
88 let mut widths = vec![0; self.get_column_count()];
90 let sample_size = 100.min(self.get_row_count());
91
92 for (i, name) in self.get_column_names().iter().enumerate() {
94 if i < widths.len() {
95 widths[i] = name.len();
96 }
97 }
98
99 for row_idx in 0..sample_size {
101 if let Some(row) = self.get_row(row_idx) {
102 for (col_idx, value) in row.iter().enumerate() {
103 if col_idx < widths.len() {
104 widths[col_idx] = widths[col_idx].max(value.len());
105 }
106 }
107 }
108 }
109
110 widths
111 }
112
113 fn get_cell_value(&self, row: usize, col: usize) -> Option<String> {
116 self.get_row(row).and_then(|r| r.get(col).cloned())
117 }
118
119 fn get_display_value(&self, row: usize, col: usize) -> String {
122 self.get_cell_value(row, col).unwrap_or_default()
123 }
124
125 fn get_column_type(&self, _column_index: usize) -> DataType {
128 DataType::Unknown
131 }
132
133 fn get_column_types(&self) -> Vec<DataType> {
136 vec![DataType::Unknown; self.get_column_count()]
138 }
139}
140
141pub trait DataViewProvider: DataProvider {
146 fn apply_filter(&mut self, filter: &str) -> Result<(), String>;
149
150 fn clear_filters(&mut self);
152
153 fn get_filtered_count(&self) -> usize {
155 self.get_row_count()
157 }
158
159 fn sort_by(&mut self, column_index: usize, ascending: bool) -> Result<(), String>;
161
162 fn clear_sort(&mut self);
164
165 fn is_row_visible(&self, row_index: usize) -> bool {
167 row_index < self.get_row_count()
168 }
169
170 fn get_sorted_indices(&self, _column_index: usize, _ascending: bool) -> Vec<usize> {
173 (0..self.get_row_count()).collect()
175 }
176
177 fn is_sorted(&self) -> bool {
179 false
180 }
181
182 fn get_sort_state(&self) -> Option<(usize, bool)> {
184 None }
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[derive(Debug)]
194 struct MockDataProvider {
195 columns: Vec<String>,
196 rows: Vec<Vec<String>>,
197 }
198
199 impl DataProvider for MockDataProvider {
200 fn get_row(&self, index: usize) -> Option<Vec<String>> {
201 self.rows.get(index).cloned()
202 }
203
204 fn get_column_names(&self) -> Vec<String> {
205 self.columns.clone()
206 }
207
208 fn get_row_count(&self) -> usize {
209 self.rows.len()
210 }
211
212 fn get_column_count(&self) -> usize {
213 self.columns.len()
214 }
215 }
216
217 #[test]
218 fn test_data_provider_basics() {
219 let provider = MockDataProvider {
220 columns: vec!["ID".to_string(), "Name".to_string(), "Age".to_string()],
221 rows: vec![
222 vec!["1".to_string(), "Alice".to_string(), "30".to_string()],
223 vec!["2".to_string(), "Bob".to_string(), "25".to_string()],
224 ],
225 };
226
227 assert_eq!(provider.get_row_count(), 2);
228 assert_eq!(provider.get_column_count(), 3);
229 assert_eq!(provider.get_column_names(), vec!["ID", "Name", "Age"]);
230 assert_eq!(
231 provider.get_row(0),
232 Some(vec!["1".to_string(), "Alice".to_string(), "30".to_string()])
233 );
234 assert_eq!(provider.get_cell_value(1, 1), Some("Bob".to_string()));
235 }
236
237 #[test]
238 fn test_get_visible_rows() {
239 let provider = MockDataProvider {
240 columns: vec!["Col1".to_string()],
241 rows: (0..10).map(|i| vec![format!("Row{}", i)]).collect(),
242 };
243
244 let visible = provider.get_visible_rows(2, 3);
245 assert_eq!(visible.len(), 3);
246 assert_eq!(visible[0], vec!["Row2"]);
247 assert_eq!(visible[2], vec!["Row4"]);
248 }
249
250 #[test]
251 fn test_column_widths() {
252 let provider = MockDataProvider {
253 columns: vec!["ID".to_string(), "LongColumnName".to_string()],
254 rows: vec![
255 vec!["123456".to_string(), "Short".to_string()],
256 vec!["1".to_string(), "Value".to_string()],
257 ],
258 };
259
260 let widths = provider.get_column_widths();
261 assert_eq!(widths[0], 6); assert_eq!(widths[1], 14); }
264}