1use crate::core::CompiledFormula;
2use crate::core::SharedVec;
3use serde::{Deserialize, Serialize};
4
5use super::bitmask::Bitmask;
6use super::cell::{CellType, generate_unique_id};
7use super::result_data::ResultData;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum ColumnData {
12 Integer {
14 validity: Bitmask,
16 values: SharedVec<i64>,
18 },
19 Float {
21 validity: Bitmask,
23 values: SharedVec<f64>,
25 },
26 Any(SharedVec<ResultData>),
29}
30
31impl ColumnData {
32 pub(crate) fn new(size: usize) -> Self {
33 Self::Integer {
34 validity: Bitmask::with_size(size),
35 values: vec![0; size].into(),
36 }
37 }
38
39 pub fn len(&self) -> usize {
41 match self {
42 Self::Integer { validity, .. } => validity.len,
43 Self::Float { validity, .. } => validity.len,
44 Self::Any(v) => v.len(),
45 }
46 }
47
48 pub fn is_empty(&self) -> bool {
50 self.len() == 0
51 }
52
53 pub(crate) fn push(&mut self, value: ResultData) {
54 let index = self.len();
55 self.insert(index, value);
56 }
57
58 pub fn get(&self, index: usize) -> Option<ResultData> {
64 if index >= self.len() {
65 return None;
66 }
67 match self {
68 Self::Integer { validity, values } => {
69 if validity.get(index) {
70 Some(ResultData::Integer(values[index]))
71 } else {
72 Some(ResultData::None)
73 }
74 }
75 Self::Float { validity, values } => {
76 if validity.get(index) {
77 Some(ResultData::Float(values[index]))
78 } else {
79 Some(ResultData::None)
80 }
81 }
82 Self::Any(v) => Some(v[index].clone()),
83 }
84 }
85
86 pub(crate) fn demote_to_any(&mut self) {
87 let len = self.len();
88 let mut any = Vec::with_capacity(len);
89 for i in 0..len {
90 any.push(self.get(i).unwrap());
91 }
92 *self = Self::Any(any.into());
93 }
94
95 pub(crate) fn promote_to_float(&mut self) {
96 if let Self::Integer { validity, values } = self {
97 let float_values = values.iter().map(|&i| i as f64).collect();
98 *self = Self::Float {
99 validity: validity.clone(),
100 values: float_values,
101 };
102 }
103 }
104
105 pub(crate) fn resize(&mut self, size: usize) {
106 match self {
107 Self::Integer { validity, values } => {
108 values.resize(size, 0);
109 *validity = Bitmask::with_size(size);
110 }
111 Self::Float { validity, values } => {
112 values.resize(size, 0.0);
113 *validity = Bitmask::with_size(size);
114 }
115 Self::Any(v) => {
116 v.resize(size, ResultData::None);
117 }
118 }
119 }
120
121 pub(crate) fn set(&mut self, index: usize, value: ResultData) {
122 if index >= self.len() {
123 return;
124 }
125 match self {
126 Self::Integer { validity, values } => match value {
127 ResultData::Integer(i) => {
128 validity.set(index, true);
129 values[index] = i;
130 }
131 ResultData::Float(f) => {
132 self.promote_to_float();
133 self.set(index, ResultData::Float(f));
134 }
135 ResultData::None => {
136 validity.set(index, false);
137 values[index] = 0;
138 }
139 _ => {
140 self.demote_to_any();
141 if let Self::Any(v) = self {
142 v[index] = value;
143 }
144 }
145 },
146 Self::Float { validity, values } => match value {
147 ResultData::Float(f) => {
148 validity.set(index, true);
149 values[index] = f;
150 }
151 ResultData::Integer(i) => {
152 validity.set(index, true);
153 values[index] = i as f64;
154 }
155 ResultData::None => {
156 validity.set(index, false);
157 values[index] = 0.0;
158 }
159 _ => {
160 self.demote_to_any();
161 if let Self::Any(v) = self {
162 v[index] = value;
163 }
164 }
165 },
166 Self::Any(v) => {
167 v[index] = value;
168 }
169 }
170 }
171
172 pub(crate) fn insert(&mut self, index: usize, value: ResultData) {
173 match self {
174 Self::Integer { validity, values } => match value {
175 ResultData::Integer(i) => {
176 validity.insert(index, true);
177 values.insert(index, i);
178 }
179 ResultData::Float(f) => {
180 self.promote_to_float();
181 self.insert(index, ResultData::Float(f));
182 }
183 ResultData::None => {
184 validity.insert(index, false);
185 values.insert(index, 0);
186 }
187 _ => {
188 self.demote_to_any();
189 if let Self::Any(v) = self {
190 v.insert(index, value);
191 }
192 }
193 },
194 Self::Float { validity, values } => match value {
195 ResultData::Float(f) => {
196 validity.insert(index, true);
197 values.insert(index, f);
198 }
199 ResultData::Integer(i) => {
200 validity.insert(index, true);
201 values.insert(index, i as f64);
202 }
203 ResultData::None => {
204 validity.insert(index, false);
205 values.insert(index, 0.0);
206 }
207 _ => {
208 self.demote_to_any();
209 if let Self::Any(v) = self {
210 v.insert(index, value);
211 }
212 }
213 },
214 Self::Any(v) => {
215 v.insert(index, value);
216 }
217 }
218 }
219
220 pub(crate) fn remove(&mut self, index: usize) {
221 match self {
222 Self::Integer { validity, values } => {
223 validity.remove(index);
224 values.remove(index);
225 }
226 Self::Float { validity, values } => {
227 validity.remove(index);
228 values.remove(index);
229 }
230 Self::Any(v) => {
231 v.remove(index);
232 }
233 }
234 }
235
236 pub(crate) fn drain<R: std::ops::RangeBounds<usize> + Clone>(&mut self, range: R) {
237 match self {
238 Self::Integer { validity, values } => {
239 validity.drain(range.clone());
240 values.drain(range);
241 }
242 Self::Float { validity, values } => {
243 validity.drain(range.clone());
244 values.drain(range);
245 }
246 Self::Any(v) => {
247 v.drain(range);
248 }
249 }
250 }
251}
252
253impl Default for ColumnData {
254 fn default() -> Self {
255 Self::Integer {
256 validity: Bitmask::with_size(0),
257 values: SharedVec::new(),
258 }
259 }
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct DataColumn {
268 #[serde(default = "generate_unique_id")]
271 pub id: u64,
272 #[serde(default)]
274 pub name: String,
275 #[serde(default)]
277 pub width: Option<f64>,
278 #[serde(skip, default)]
280 pub(crate) data: ColumnData,
281 pub(crate) src: SharedVec<String>,
283 #[serde(default)]
285 pub(crate) cell_types: SharedVec<CellType>,
286 #[serde(skip, default)]
288 pub(crate) compiled_src: SharedVec<CompiledFormula>,
289 #[serde(skip, default)]
291 pub(crate) dirty_indices: SharedVec<usize>,
292 #[serde(default)]
295 pub(crate) styles: SharedVec<Option<crate::core::CellStyle>>,
296}
297
298pub(crate) struct ColumnPosition {
299 pub row: usize,
300 pub char_offset: usize,
301}
302
303impl DataColumn {
304 pub fn new(size: usize) -> Self {
306 Self {
307 id: generate_unique_id(),
308 name: String::new(),
309 width: None,
310 data: ColumnData::new(size),
311 src: vec![String::new(); size].into(),
312 cell_types: vec![CellType::Empty; size].into(),
313 compiled_src: vec![CompiledFormula::default(); size].into(),
314 dirty_indices: SharedVec::new(),
315 styles: vec![None; size].into(),
316 }
317 }
318
319 pub fn len(&self) -> usize {
321 self.src.len()
322 }
323
324 pub fn is_empty(&self) -> bool {
326 self.src.is_empty()
327 }
328
329 pub fn src(&self, row: usize) -> Option<&str> {
331 self.src.get(row).map(String::as_str)
332 }
333
334 pub fn value(&self, row: usize) -> Option<ResultData> {
336 self.data.get(row)
337 }
338
339 pub fn values(&self) -> &ColumnData {
342 &self.data
343 }
344
345 pub fn cell_type(&self, row: usize) -> Option<CellType> {
347 self.cell_types.get(row).copied()
348 }
349
350 pub fn set_cell_type(&mut self, row: usize, cell_type: CellType) {
352 if row < self.cell_types.len() {
353 self.cell_types[row] = cell_type;
354 }
355 }
356
357 pub fn compiled(&self, row: usize) -> Option<&CompiledFormula> {
360 self.compiled_src.get(row)
361 }
362
363 pub fn style(&self, row: usize) -> Option<&crate::core::CellStyle> {
365 self.styles.get(row).and_then(Option::as_ref)
366 }
367
368 pub(crate) fn mark_dirty(&mut self, row: usize) {
369 if !self.dirty_indices.contains(&row) {
370 self.dirty_indices.push(row);
371 }
372 }
373
374 #[cfg(test)]
375 pub(crate) fn from_src(name: impl Into<String>, src: Vec<String>) -> Self {
376 let mut col = Self::new(src.len());
377 col.name = name.into();
378 col.src = src.into();
379 col
380 }
381
382 pub(crate) fn rebuild_after_load(&mut self) {
383 let size = self.src.len();
384 self.data.resize(size);
385 self.cell_types.resize(size, CellType::Empty);
386 self.compiled_src = vec![CompiledFormula::default(); size].into();
387 self.styles.resize(size, None);
388 }
389
390 pub(crate) fn push_row(&mut self) {
391 self.src.push(String::new());
392 self.cell_types.push(CellType::Empty);
393 self.compiled_src.push(CompiledFormula::default());
394 self.data.push(ResultData::None);
395 self.styles.push(None);
396 }
397
398 pub(crate) fn insert_row(&mut self, index: usize) {
399 if index >= self.len() {
400 self.push_row();
401 return;
402 }
403 self.src.insert(index, String::new());
404 self.cell_types.insert(index, CellType::Empty);
405 self.compiled_src.insert(index, CompiledFormula::default());
406 self.data.insert(index, ResultData::None);
407 self.styles.insert(index, None);
408 self.shift_dirty_after_insert(index, 1);
409 }
410
411 pub(crate) fn remove_row(&mut self, index: usize) {
412 if index >= self.len() {
413 return;
414 }
415 self.src.remove(index);
416 self.cell_types.remove(index);
417 self.compiled_src.remove(index);
418 self.data.remove(index);
419 self.styles.remove(index);
420 self.drop_dirty_range(index, index + 1);
421 }
422
423 pub(crate) fn drain_rows<R: std::ops::RangeBounds<usize>>(&mut self, range: R) {
424 let start = match range.start_bound() {
425 std::ops::Bound::Included(&n) => n,
426 std::ops::Bound::Excluded(&n) => n + 1,
427 std::ops::Bound::Unbounded => 0,
428 };
429 let end = match range.end_bound() {
430 std::ops::Bound::Included(&n) => n + 1,
431 std::ops::Bound::Excluded(&n) => n,
432 std::ops::Bound::Unbounded => self.len(),
433 };
434 let start = start.min(self.len());
435 let end = end.min(self.len());
436 if start >= end {
437 return;
438 }
439 self.src.drain(start..end);
440 self.cell_types.drain(start..end);
441 self.compiled_src.drain(start..end);
442 self.data.drain(start..end);
443 self.styles.drain(start..end);
444 self.drop_dirty_range(start, end);
445 }
446
447 pub(crate) fn resize_rows(&mut self, len: usize) {
448 while self.len() < len {
449 self.push_row();
450 }
451 if self.len() > len {
452 self.drain_rows(len..);
453 }
454 }
455
456 fn drop_dirty_range(&mut self, start: usize, end: usize) {
457 let removed = end - start;
458 self.dirty_indices.retain(|&i| i < start || i >= end);
459 for i in self.dirty_indices.iter_mut() {
460 if *i >= end {
461 *i -= removed;
462 }
463 }
464 }
465
466 fn shift_dirty_after_insert(&mut self, index: usize, count: usize) {
467 for i in self.dirty_indices.iter_mut() {
468 if *i >= index {
469 *i += count;
470 }
471 }
472 }
473
474 pub(crate) fn insert(&mut self, position: ColumnPosition, input: &str) {
475 let ColumnPosition { row, char_offset } = position;
476 let index = row;
477 if index < self.src.len() {
478 if self.src[index].is_empty() {
479 self.src[index].push_str(input);
480 } else {
481 self.src[index].insert_str(char_offset, input);
482 }
483 } else {
484 self.resize_rows(index + 1);
485 self.src[index] = input.to_string();
486 }
487 }
488}