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(skip, default)]
298 pub(crate) data: ColumnData,
299 pub(crate) src: SharedVec<String>,
302 #[serde(default)]
304 pub(crate) cell_types: SharedVec<CellType>,
305 #[serde(skip, default)]
307 pub(crate) compiled_src: SharedVec<CompiledFormula>,
308 #[serde(skip, default)]
310 pub(crate) dirty_indices: SharedVec<usize>,
311 #[serde(default)]
314 pub(crate) styles: SharedVec<Option<crate::core::CellStyle>>,
315}
316
317pub(crate) struct ColumnPosition {
318 pub row: usize,
319 pub char_offset: usize,
320}
321
322impl DataColumn {
323 pub fn new(size: usize) -> Self {
326 Self {
327 id: generate_unique_id(),
328 name: String::new(),
329 data: ColumnData::new(size),
330 src: vec![String::new(); size].into(),
331 cell_types: vec![CellType::Auto; size].into(),
332 compiled_src: vec![CompiledFormula::default(); size].into(),
333 dirty_indices: SharedVec::new(),
334 styles: vec![None; size].into(),
335 }
336 }
337
338 pub fn len(&self) -> usize {
340 self.src.len()
341 }
342
343 pub fn is_empty(&self) -> bool {
345 self.src.is_empty()
346 }
347
348 pub fn src(&self, row: usize) -> Option<&str> {
350 self.src.get(row).map(String::as_str)
351 }
352
353 pub fn value(&self, row: usize) -> Option<ResultData> {
358 self.data.get(row)
359 }
360
361 pub fn values(&self) -> &ColumnData {
364 &self.data
365 }
366
367 pub fn cell_type(&self, row: usize) -> Option<CellType> {
369 self.cell_types.get(row).copied()
370 }
371
372 pub fn set_cell_type(&mut self, row: usize, cell_type: CellType) {
374 if row < self.cell_types.len() {
375 self.cell_types[row] = cell_type;
376 }
377 }
378
379 pub fn compiled(&self, row: usize) -> Option<&CompiledFormula> {
382 self.compiled_src.get(row)
383 }
384
385 pub fn style(&self, row: usize) -> Option<&crate::core::CellStyle> {
387 self.styles.get(row).and_then(Option::as_ref)
388 }
389
390 pub(crate) fn mark_dirty(&mut self, row: usize) {
391 if !self.dirty_indices.contains(&row) {
392 self.dirty_indices.push(row);
393 }
394 }
395
396 #[cfg(test)]
403 pub(crate) fn from_src(name: impl Into<String>, src: Vec<String>) -> Self {
404 let mut col = Self::new(src.len());
405 col.name = name.into();
406 col.src = src.into();
407 col
408 }
409
410 pub(crate) fn rebuild_after_load(&mut self) {
416 let size = self.src.len();
417 self.data.resize(size);
418 self.cell_types.resize(size, CellType::Auto);
419 self.compiled_src = vec![CompiledFormula::default(); size].into();
420 self.styles.resize(size, None);
421 }
422
423 pub(crate) fn push_row(&mut self) {
425 self.src.push(String::new());
426 self.cell_types.push(CellType::Auto);
427 self.compiled_src.push(CompiledFormula::default());
428 self.data.push(ResultData::None);
429 self.styles.push(None);
430 }
431
432 pub(crate) fn insert_row(&mut self, index: usize) {
435 if index >= self.len() {
436 self.push_row();
437 return;
438 }
439 self.src.insert(index, String::new());
440 self.cell_types.insert(index, CellType::Auto);
441 self.compiled_src.insert(index, CompiledFormula::default());
442 self.data.insert(index, ResultData::None);
443 self.styles.insert(index, None);
444 self.shift_dirty_after_insert(index, 1);
445 }
446
447 pub(crate) fn remove_row(&mut self, index: usize) {
450 if index >= self.len() {
451 return;
452 }
453 self.src.remove(index);
454 self.cell_types.remove(index);
455 self.compiled_src.remove(index);
456 self.data.remove(index);
457 self.styles.remove(index);
458 self.drop_dirty_range(index, index + 1);
459 }
460
461 pub(crate) fn drain_rows<R: std::ops::RangeBounds<usize>>(&mut self, range: R) {
466 let start = match range.start_bound() {
467 std::ops::Bound::Included(&n) => n,
468 std::ops::Bound::Excluded(&n) => n + 1,
469 std::ops::Bound::Unbounded => 0,
470 };
471 let end = match range.end_bound() {
472 std::ops::Bound::Included(&n) => n + 1,
473 std::ops::Bound::Excluded(&n) => n,
474 std::ops::Bound::Unbounded => self.len(),
475 };
476 let start = start.min(self.len());
477 let end = end.min(self.len());
478 if start >= end {
479 return;
480 }
481 self.src.drain(start..end);
482 self.cell_types.drain(start..end);
483 self.compiled_src.drain(start..end);
484 self.data.drain(start..end);
485 self.styles.drain(start..end);
486 self.drop_dirty_range(start, end);
487 }
488
489 pub(crate) fn resize_rows(&mut self, len: usize) {
492 while self.len() < len {
493 self.push_row();
494 }
495 if self.len() > len {
496 self.drain_rows(len..);
497 }
498 }
499
500 fn drop_dirty_range(&mut self, start: usize, end: usize) {
502 let removed = end - start;
503 self.dirty_indices.retain(|&i| i < start || i >= end);
504 for i in self.dirty_indices.iter_mut() {
505 if *i >= end {
506 *i -= removed;
507 }
508 }
509 }
510
511 fn shift_dirty_after_insert(&mut self, index: usize, count: usize) {
513 for i in self.dirty_indices.iter_mut() {
514 if *i >= index {
515 *i += count;
516 }
517 }
518 }
519
520 pub(crate) fn insert(&mut self, position: ColumnPosition, input: &str) {
522 let ColumnPosition { row, char_offset } = position;
523 let index = row;
524 if index < self.src.len() {
525 if self.src[index].is_empty() {
526 self.src[index].push_str(input);
527 } else {
528 self.src[index].insert_str(char_offset, input);
529 }
530 } else {
531 self.resize_rows(index + 1);
533 self.src[index] = input.to_string();
534 }
535 }
536}