1use std::iter::FromIterator;
2
3use crate::{grid::records::vec_records::Text, Table};
4
5use super::IndexBuilder;
6
7#[derive(Debug, Default, Clone)]
40pub struct Builder {
41 data: Vec<Vec<Text<String>>>,
43 count_columns: usize,
45 empty_text: Text<String>,
47}
48
49impl Builder {
50 pub fn new() -> Self {
58 Self::default()
59 }
60
61 pub fn with_capacity(count_records: usize, count_columns: usize) -> Self {
71 let mut builder = Self::new();
72 builder.data = Vec::with_capacity(count_records);
73 builder.count_columns = count_columns;
74
75 builder
76 }
77
78 pub fn from_vec(data: Vec<Vec<Text<String>>>) -> Self {
91 let count_columns = if data.is_empty() { 0 } else { data[0].len() };
92
93 Self {
94 data,
95 count_columns,
96 empty_text: Text::default(),
97 }
98 }
99
100 pub fn set_empty<T>(&mut self, text: T)
112 where
113 T: Into<String>,
114 {
115 self.empty_text = Text::new(text.into());
116 }
117
118 pub fn build(self) -> Table {
128 Table::from(self)
129 }
130
131 pub fn index(self) -> IndexBuilder {
156 IndexBuilder::from(self)
157 }
158
159 pub fn push_record<R>(&mut self, record: R)
169 where
170 R: IntoIterator,
171 R::Item: Into<String>,
172 {
173 let list = create_row(record, self.count_columns, &self.empty_text);
174 let list_length = list.len();
175
176 if !is_size_eq(self.count_columns, list_length) {
177 let size = list_length - self.count_columns;
178 resize_rows(&mut self.data, size, &self.empty_text)
179 }
180
181 self.count_columns = list_length;
182 self.data.push(list);
183 }
184
185 pub fn insert_record<R>(&mut self, index: usize, record: R)
191 where
192 R: IntoIterator,
193 R::Item: Into<String>,
194 {
195 let list = create_row(record, self.count_columns, &self.empty_text);
196 let list_length = list.len();
197
198 if !is_size_eq(self.count_columns, list_length) {
199 let size = list_length - self.count_columns;
200 resize_rows(&mut self.data, size, &self.empty_text)
201 }
202
203 self.count_columns = list_length;
204 self.data.insert(index, list);
205 }
206
207 pub fn clean(&mut self) {
231 self.count_columns -= remove_empty_columns(&mut self.data, self.count_columns);
232 remove_empty_rows(&mut self.data, self.count_columns);
233 }
234
235 pub fn remove_record(&mut self, index: usize) {
244 let _ = self.data.remove(index);
245 }
246
247 pub fn remove_column(&mut self, index: usize) {
256 for row in &mut self.data {
257 let _ = row.remove(index);
258 }
259
260 self.count_columns -= 1;
261 }
262
263 pub fn push_column<I>(&mut self, column: I)
265 where
266 I: IntoIterator,
267 I::Item: Into<String>,
268 {
269 let mut iter = column.into_iter();
270
271 for row in self.data.iter_mut() {
272 let text = iter
273 .next()
274 .map(Into::into)
275 .map(Text::new)
276 .unwrap_or(self.empty_text.clone());
277
278 row.push(text);
279 }
280
281 for text in iter {
282 let text = Text::new(text.into());
283
284 let mut row = Vec::with_capacity(self.count_columns + 1);
285 for _ in 0..self.count_columns {
286 row.push(self.empty_text.clone());
287 }
288
289 row.push(text);
290 self.data.push(row);
291 }
292
293 self.count_columns += 1;
294 }
295
296 pub fn insert_column<I>(&mut self, index: usize, column: I)
304 where
305 I: IntoIterator,
306 I::Item: Into<String>,
307 {
308 let mut iter = column.into_iter();
309
310 for row in self.data.iter_mut() {
311 let text = iter
312 .next()
313 .map(Into::into)
314 .map(Text::new)
315 .unwrap_or(self.empty_text.clone());
316
317 row.insert(index, text);
318 }
319
320 for text in iter {
321 let text = Text::new(text.into());
322
323 let mut row = Vec::with_capacity(self.count_columns + 1);
324 for _ in 0..index {
325 row.push(self.empty_text.clone());
326 }
327
328 row.push(text);
329
330 for _ in index..self.count_columns {
331 row.push(self.empty_text.clone());
332 }
333 }
334
335 self.count_columns += 1;
336 }
337
338 pub fn clear(&mut self) {
340 self.data.clear();
341 self.count_columns = 0;
342 }
343
344 pub fn count_columns(&self) -> usize {
346 self.count_columns
347 }
348
349 pub fn count_records(&self) -> usize {
354 self.data.len()
355 }
356}
357
358impl From<Builder> for Vec<Vec<String>> {
359 fn from(builder: Builder) -> Self {
360 builder
361 .data
362 .into_iter()
363 .map(|row| row.into_iter().map(Text::into_inner).collect())
364 .collect()
365 }
366}
367
368impl From<Builder> for Vec<Vec<Text<String>>> {
369 fn from(builder: Builder) -> Self {
370 builder.data
371 }
372}
373
374impl<K, V, S> From<std::collections::HashMap<K, V, S>> for Builder
375where
376 K: ToString,
377 V: ToString,
378{
379 fn from(m: std::collections::HashMap<K, V, S>) -> Self {
380 let mut b = Self::with_capacity(m.len(), 2);
381 for (k, v) in m {
382 b.push_record([k.to_string(), v.to_string()]);
383 }
384
385 b
386 }
387}
388
389impl<K, V> From<std::collections::BTreeMap<K, V>> for Builder
390where
391 K: ToString,
392 V: ToString,
393{
394 fn from(m: std::collections::BTreeMap<K, V>) -> Self {
395 let mut b = Self::with_capacity(m.len(), 2);
396 for (k, v) in m {
397 b.push_record([k.to_string(), v.to_string()]);
398 }
399
400 b
401 }
402}
403
404impl<V> From<std::collections::HashSet<V>> for Builder
405where
406 V: ToString,
407{
408 fn from(m: std::collections::HashSet<V>) -> Self {
409 let mut b = Self::with_capacity(m.len(), 1);
410 for v in m {
411 b.push_record([v.to_string()]);
412 }
413
414 b
415 }
416}
417
418impl<V> From<std::collections::BTreeSet<V>> for Builder
419where
420 V: ToString,
421{
422 fn from(m: std::collections::BTreeSet<V>) -> Self {
423 let mut b = Self::with_capacity(m.len(), 1);
424 for v in m {
425 b.push_record([v.to_string()]);
426 }
427
428 b
429 }
430}
431
432impl<R> FromIterator<R> for Builder
433where
434 R: IntoIterator,
435 R::Item: Into<String>,
436{
437 fn from_iter<T: IntoIterator<Item = R>>(iter: T) -> Self {
438 let mut builder = Self::new();
439 for row in iter {
440 builder.push_record(row);
441 }
442
443 builder
444 }
445}
446
447impl<D> Extend<D> for Builder
448where
449 D: Into<String>,
450{
451 fn extend<T: IntoIterator<Item = D>>(&mut self, iter: T) {
452 self.push_record(iter);
453 }
454}
455
456impl From<Vec<Vec<String>>> for Builder {
457 fn from(data: Vec<Vec<String>>) -> Self {
458 let mut data = data
459 .into_iter()
460 .map(|row| row.into_iter().map(Text::new).collect())
461 .collect();
462
463 let count_columns = equalize_row_length(&mut data);
464
465 Self {
466 data,
467 count_columns,
468 empty_text: Text::default(),
469 }
470 }
471}
472
473impl From<Vec<Vec<Text<String>>>> for Builder {
474 fn from(mut data: Vec<Vec<Text<String>>>) -> Self {
475 let count_columns = equalize_row_length(&mut data);
476
477 Self {
478 data,
479 count_columns,
480 empty_text: Text::default(),
481 }
482 }
483}
484
485fn create_row<R>(row: R, size: usize, default: &Text<String>) -> Vec<Text<String>>
486where
487 R: IntoIterator,
488 R::Item: Into<String>,
489{
490 let mut list = Vec::with_capacity(size);
491 for text in row {
492 let text = text.into();
493 let text = Text::new(text);
494 list.push(text);
495 }
496
497 if list.len() < size {
498 for _ in 0..size - list.len() {
499 let text = default.clone();
500 list.push(text);
501 }
502 }
503
504 list
505}
506
507fn remove_empty_columns(data: &mut [Vec<Text<String>>], count_columns: usize) -> usize {
508 let mut deleted = 0;
509 for col in 0..count_columns {
510 let col = col - deleted;
511
512 let mut is_empty_column = true;
513 for row in data.iter() {
514 let text = &row[col];
515 if !text.as_ref().is_empty() {
516 is_empty_column = false;
517 break;
518 }
519 }
520
521 if is_empty_column {
522 for row in data.iter_mut() {
523 let _ = row.remove(col);
524 }
525
526 deleted += 1;
527 }
528 }
529
530 deleted
531}
532
533fn remove_empty_rows(data: &mut Vec<Vec<Text<String>>>, count_columns: usize) {
534 let mut deleted = 0;
535
536 for row in 0..data.len() {
537 let row = row - deleted;
538
539 let mut is_empty_row = true;
540 for col in 0..count_columns {
541 let cell = &data[row][col];
542 if !cell.as_ref().is_empty() {
543 is_empty_row = false;
544 break;
545 }
546 }
547
548 if is_empty_row {
549 let _ = data.remove(row);
550 deleted += 1;
551 }
552 }
553}
554
555fn resize_rows(data: &mut Vec<Vec<Text<String>>>, size: usize, empty_text: &Text<String>) {
556 for row in data {
557 append_vec(row, empty_text.clone(), size);
558 }
559}
560
561fn append_vec<T>(v: &mut Vec<T>, value: T, n: usize)
562where
563 T: Clone,
564{
565 for _ in 0..n {
566 v.push(value.clone());
567 }
568}
569
570fn is_size_eq(expected: usize, new: usize) -> bool {
571 use std::cmp::Ordering;
572
573 match new.cmp(&expected) {
574 Ordering::Less => {
575 unreachable!("must be impossible due to the assumptions/checks we do");
576 }
577 Ordering::Greater => false,
578 Ordering::Equal => true,
579 }
580}
581
582fn equalize_row_length(data: &mut Vec<Vec<Text<String>>>) -> usize {
583 if data.is_empty() {
584 return 0;
585 }
586
587 let first_row_length = data[0].len();
588 let init = (first_row_length, true);
589 let (count_columns, is_consistent) = data.iter().fold(init, |mut acc, cur| {
590 let length = cur.len();
591 acc.1 = acc.1 && acc.0 == length;
592 acc.0 = std::cmp::max(acc.0, length);
593 acc
594 });
595
596 if !is_consistent {
597 let empty_text = Text::default();
598 for row in data {
599 let size = count_columns - row.len();
600 append_vec(row, empty_text.clone(), size);
601 }
602 }
603
604 count_columns
605}