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