1use crate::csv_handler::CellRange;
7use anyhow::Result;
8
9pub trait DataReader: Send + Sync {
11 fn read(&self, path: &str) -> Result<Vec<Vec<String>>>;
13
14 fn read_with_headers(&self, path: &str) -> Result<Vec<Vec<String>>>;
16
17 fn read_range(&self, path: &str, range: &CellRange) -> Result<Vec<Vec<String>>>;
19
20 fn read_as_json(&self, path: &str) -> Result<String>;
22
23 fn supports_format(&self, path: &str) -> bool;
25}
26
27pub trait DataWriter: Send + Sync {
29 fn write(&self, path: &str, data: &[Vec<String>], options: DataWriteOptions) -> Result<()>;
31
32 fn write_range(
34 &self,
35 path: &str,
36 data: &[Vec<String>],
37 start_row: usize,
38 start_col: usize,
39 ) -> Result<()>;
40
41 fn append(&self, path: &str, data: &[Vec<String>]) -> Result<()>;
43
44 fn supports_format(&self, path: &str) -> bool;
46}
47
48#[derive(Debug, Clone, Default)]
50pub struct DataWriteOptions {
51 pub sheet_name: Option<String>,
53 pub column_names: Option<Vec<String>>,
55 pub include_headers: bool,
57}
58
59pub trait FileHandler: DataReader + DataWriter {
61 fn format_name(&self) -> &'static str;
63
64 fn supported_extensions(&self) -> &'static [&'static str];
66}
67
68pub trait FormatDetector: Send + Sync {
70 fn detect_format(&self, path: &str) -> Result<String>;
72
73 fn is_supported(&self, format: &str) -> bool;
75
76 fn supported_formats(&self) -> Vec<String>;
78}
79
80pub trait SchemaProvider: Send + Sync {
82 fn get_schema(&self, path: &str) -> Result<Vec<(String, String)>>;
84
85 fn get_column_names(&self, path: &str) -> Result<Vec<String>>;
87
88 fn get_row_count(&self, path: &str) -> Result<usize>;
90
91 fn get_column_count(&self, path: &str) -> Result<usize>;
93}
94
95pub trait StreamingReader: Send + Sync {
97 fn open(&self, path: &str) -> Result<Box<dyn StreamingReadIterator>>;
99}
100
101pub trait StreamingReadIterator: Iterator<Item = Result<Vec<String>>> {
103 fn current_row(&self) -> usize;
105}
106
107pub trait StreamingWriter: Send + Sync {
109 fn create(&self, path: &str) -> Result<Box<dyn StreamingWriteHandle>>;
111}
112
113pub trait StreamingWriteHandle: Send + Sync {
115 fn write_row(&mut self, row: &[String]) -> Result<()>;
117
118 fn rows_written(&self) -> usize;
120
121 fn flush(&mut self) -> Result<()>;
123}
124
125pub trait CellRangeProvider: Send + Sync {
127 fn parse_range(&self, range_str: &str) -> Result<CellRange>;
129
130 fn to_cell_reference(&self, row: usize, col: usize) -> String;
132
133 fn from_cell_reference(&self, cell: &str) -> Result<(usize, usize)>;
135}
136
137pub trait SortOperator: Send + Sync {
139 fn sort(&self, data: &mut Vec<Vec<String>>, column: usize, ascending: bool) -> Result<()>;
140}
141
142pub trait FilterOperator: Send + Sync {
144 fn filter(
145 &self,
146 data: &[Vec<String>],
147 column: usize,
148 condition: FilterCondition,
149 ) -> Result<Vec<Vec<String>>>;
150}
151
152pub trait TransformOperator: Send + Sync {
154 fn transform(&self, data: &mut Vec<Vec<String>>, operation: TransformOperation) -> Result<()>;
155}
156
157pub trait DataOperator: SortOperator + FilterOperator + TransformOperator {}
159
160#[derive(Debug, Clone)]
162pub enum FilterCondition {
163 Equals(String),
164 NotEquals(String),
165 GreaterThan(String),
166 GreaterThanOrEqual(String),
167 LessThan(String),
168 LessThanOrEqual(String),
169 Contains(String),
170 StartsWith(String),
171 EndsWith(String),
172 Regex(String),
173}
174
175#[derive(Debug, Clone)]
177pub enum TransformOperation {
178 RenameColumn {
179 from: usize,
180 to: String,
181 },
182 DropColumn(usize),
183 AddColumn {
184 name: String,
185 formula: Option<String>,
186 },
187 FillNa {
188 column: usize,
189 value: String,
190 },
191}