1use crate::error::{DcsvError, DcsvResult};
4use crate::value::{Value, ValueLimiter, ValueType};
5use crate::vcont::VCont;
6use std::cmp::Ordering;
7use std::collections::HashMap;
8
9pub const SCHEMA_HEADER: &str = "column,type,default,variant,pattern";
11
12#[derive(Clone)]
18pub struct VirtualData {
19 pub columns: Vec<Column>,
20 pub rows: Vec<Row>,
21}
22
23impl Default for VirtualData {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl VCont for VirtualData {
30 fn new() -> Self {
32 Self {
33 columns: vec![],
34 rows: vec![],
35 }
36 }
37
38 fn move_row(&mut self, src_index: usize, target_index: usize) -> DcsvResult<()> {
40 let row_count = self.get_row_count();
41 if src_index >= row_count || target_index >= row_count {
42 return Err(DcsvError::OutOfRangeError);
43 }
44
45 let move_direction = src_index.cmp(&target_index);
46 match move_direction {
47 Ordering::Greater => {
49 let mut index = src_index;
50 let mut next = index - 1;
51 while next >= target_index {
52 self.rows.swap(index, next);
53
54 if next == 0 {
56 break;
57 }
58
59 index -= 1;
61 next -= 1;
62 }
63 }
64 Ordering::Less => {
65 let mut index = src_index;
67 let mut next = index + 1;
68 while next <= target_index {
69 self.rows.swap(index, next);
70
71 index += 1;
73 next += 1;
74 }
75 }
76 Ordering::Equal => (),
77 }
78 Ok(())
79 }
80
81 fn move_column(&mut self, src_index: usize, target_index: usize) -> DcsvResult<()> {
83 let column_count = self.get_column_count();
84 if src_index >= column_count || target_index >= column_count {
85 return Err(DcsvError::OutOfRangeError);
86 }
87
88 let move_direction = src_index.cmp(&target_index);
89 match move_direction {
90 Ordering::Greater => {
92 let mut index = src_index;
93 let mut next = index - 1;
94 while next >= target_index {
95 self.columns.swap(index, next);
96
97 if next == 0 {
99 break;
100 }
101
102 index -= 1;
104 next -= 1;
105 }
106 }
107 Ordering::Less => {
108 let mut index = src_index;
110 let mut next = index + 1;
111 while next <= target_index {
112 self.columns.swap(index, next);
113
114 index += 1;
116 next += 1;
117 }
118 }
119 Ordering::Equal => (),
120 }
121 Ok(())
122 }
123
124 fn rename_column(&mut self, column_index: usize, new_name: &str) -> DcsvResult<()> {
131 let next_column_index = self.try_get_column_index(new_name);
132
133 if !self.is_valid_cell_coordinate(0, column_index) {
134 return Err(DcsvError::OutOfRangeError);
135 }
136
137 if next_column_index.is_some() {
138 return Err(DcsvError::InvalidColumn(format!(
139 "Cannot rename to \"{}\" which already exists",
140 &new_name
141 )));
142 }
143
144 let previous = self.columns[column_index].rename(new_name);
145 for row in &mut self.rows {
146 row.rename_column(&previous, new_name);
147 }
148 Ok(())
149 }
150
151 fn set_column(&mut self, column_index: usize, value: Value) -> DcsvResult<()> {
155 if !self.is_valid_cell_coordinate(0, column_index) {
156 return Err(DcsvError::OutOfRangeError);
157 }
158
159 let column = &self.columns[column_index].name;
160
161 for row in &mut self.rows {
162 row.update_cell_value(column, value.clone());
163 }
164 Ok(())
165 }
166
167 fn edit_row(&mut self, row_index: usize, values: &[Option<Value>]) -> DcsvResult<()> {
171 if values.len() != self.get_column_count() {
173 return Err(DcsvError::InsufficientRowData);
174 }
175 if !self.is_valid_cell_coordinate(row_index, 0) {
177 return Err(DcsvError::OutOfRangeError);
178 }
179
180 let col_value_iter = self.columns.iter().zip(values.iter());
181
182 for (col, value) in col_value_iter {
183 if let Some(value) = value {
184 if !col.limiter.qualify(value) {
186 return Err(DcsvError::InvalidRowData(format!(
187 "\"{}\" doesn't qualify \"{}\"'s limiter",
188 value, col.name
189 )));
190 }
191 }
192 }
193
194 let col_value_iter = self.columns.iter().zip(values.iter());
195
196 let row = self.rows.get_mut(row_index).unwrap();
199 for (col, value) in col_value_iter {
200 if let Some(value) = value {
201 row.update_cell_value(&col.name, value.clone())
202 }
203 }
204
205 Ok(())
206 }
207
208 fn set_row(&mut self, row_index: usize, values: &[Value]) -> DcsvResult<()> {
216 if values.len() != self.get_column_count() {
218 return Err(DcsvError::InsufficientRowData);
219 }
220 if !self.is_valid_cell_coordinate(row_index, 0) {
222 return Err(DcsvError::OutOfRangeError);
223 }
224
225 let col_value_iter = self.columns.iter().zip(values.iter());
226
227 for (col, value) in col_value_iter.clone() {
228 if !col.limiter.qualify(value) {
230 return Err(DcsvError::InvalidRowData(format!(
231 "\"{}\" doesn't qualify \"{}\"'s limiter",
232 value, col.name
233 )));
234 }
235 }
236
237 let row = self.rows.get_mut(row_index).unwrap();
240 for (col, value) in col_value_iter {
241 row.update_cell_value(&col.name, value.clone())
242 }
243
244 Ok(())
245 }
246
247 fn get_cell(&self, x: usize, y: usize) -> Option<&Value> {
249 if let Ok(column) = self.get_column_if_valid(x, y) {
250 self.rows[x].get_cell_value(&column.name)
251 } else {
252 None
253 }
254 }
255
256 fn set_cell(&mut self, x: usize, y: usize, value: Value) -> DcsvResult<()> {
258 let name = self.get_column_if_valid(x, y)?.name.to_owned();
259
260 self.is_valid_column_data(y, &value)?;
261 self.rows[x].update_cell_value(&name, value);
262
263 Ok(())
264 }
265
266 fn insert_row(&mut self, row_index: usize, source: Option<&[Value]>) -> DcsvResult<()> {
271 if row_index > self.get_row_count() {
272 return Err(DcsvError::InvalidColumn(format!(
273 "Cannot add row to out of range position : {}",
274 row_index
275 )));
276 }
277 let mut new_row = Row::new();
278 if let Some(source) = source {
279 self.check_row_length(source)?;
280 let iter = self.columns.iter().zip(source.iter());
281
282 for (col, value) in iter.clone() {
283 if !col.limiter.qualify(value) {
284 return Err(DcsvError::InvalidRowData(format!(
285 "\"{}\" doesn't qualify \"{}\"'s limiter",
286 value, col.name
287 )));
288 }
289 }
290
291 iter.for_each(|(col, v)| new_row.insert_cell(&col.name, v.clone()));
292 } else {
293 for col in &self.columns {
294 new_row.insert_cell(&col.name, col.get_default_value());
295 }
296 }
297 self.rows.insert(row_index, new_row);
298 Ok(())
299 }
300
301 fn insert_column(&mut self, column_index: usize, column_name: &str) -> DcsvResult<()> {
302 if column_index > self.get_column_count() {
303 return Err(DcsvError::InvalidColumn(format!(
304 "Cannot add column to out of range position : {}",
305 column_index
306 )));
307 }
308 if self.try_get_column_index(column_name).is_some() {
309 return Err(DcsvError::InvalidColumn(format!(
310 "Cannot add existing column = \"{}\"",
311 column_name
312 )));
313 }
314 let new_column = Column::new(column_name, ValueType::Text, None);
315 let default_value = new_column.get_default_value();
316 for row in &mut self.rows {
317 row.insert_cell(&new_column.name, default_value.clone());
318 }
319 self.columns.insert(column_index, new_column);
320 Ok(())
321 }
322
323 fn delete_row(&mut self, row_index: usize) -> bool {
327 let row_count = self.get_row_count();
328 if row_count == 0 || row_count < row_index {
329 return false;
330 }
331 self.rows.remove(row_index);
332 true
333 }
334
335 fn delete_column(&mut self, column_index: usize) -> DcsvResult<()> {
337 let name = self.get_column_if_valid(0, column_index)?.name.to_owned();
338
339 for row in &mut self.rows {
340 row.remove_cell(&name);
341 }
342
343 self.columns.remove(column_index);
344
345 if self.get_column_count() == 0 {
347 self.rows = vec![];
348 }
349
350 Ok(())
351 }
352
353 fn get_row_count(&self) -> usize {
355 self.rows.len()
356 }
357
358 fn get_column_count(&self) -> usize {
360 self.columns.len()
361 }
362
363 fn drop_data(&mut self) {
365 self.columns.clear();
366 self.rows.clear();
367 }
368
369 fn apply_all<F: FnMut(&mut Value)>(&mut self, mut f: F) {
371 for row in &mut self.rows {
372 for value in row.values.values_mut() {
373 f(value)
374 }
375 }
376 }
377}
378
379impl VirtualData {
380 pub fn read_only(&self) -> ReadOnlyData {
385 ReadOnlyData::from(self)
386 }
387
388 pub fn read_only_ref(&self) -> ReadOnlyDataRef {
390 ReadOnlyDataRef::from(self)
391 }
392
393 pub fn set_cell_from_string(&mut self, x: usize, y: usize, value: &str) -> DcsvResult<()> {
397 let key_column = self.get_column_if_valid(x, y)?;
398 match key_column.column_type {
399 ValueType::Text => self.set_cell(x, y, Value::Text(value.to_string())),
400 ValueType::Number => self.set_cell(
401 x,
402 y,
403 Value::Number(value.parse().map_err(|_| {
404 DcsvError::InvalidCellData(format!(
405 "Given value is \"{}\" which is not a number",
406 value
407 ))
408 })?),
409 ),
410 }
411 }
412
413 pub fn insert_column_with_type(
423 &mut self,
424 column_index: usize,
425 column_name: &str,
426 column_type: ValueType,
427 limiter: Option<ValueLimiter>,
428 placeholder: Option<Value>,
429 ) -> DcsvResult<()> {
430 if column_index > self.get_column_count() {
431 return Err(DcsvError::InvalidColumn(format!(
432 "Cannot add column to out of range position : {}",
433 column_index
434 )));
435 }
436 if self.try_get_column_index(column_name).is_some() {
437 return Err(DcsvError::InvalidColumn(format!(
438 "Cannot add existing column = \"{}\"",
439 column_name
440 )));
441 }
442 let new_column = Column::new(column_name, column_type, limiter);
443 let default_value = new_column.get_default_value();
444 for row in &mut self.rows {
445 row.insert_cell(
446 &new_column.name,
447 placeholder.clone().unwrap_or_else(|| default_value.clone()),
448 );
449 }
450 self.columns.insert(column_index, new_column);
451 Ok(())
452 }
453
454 pub fn set_limiter(
462 &mut self,
463 column: usize,
464 limiter: &ValueLimiter,
465 panic: bool,
466 ) -> DcsvResult<()> {
467 let column = &mut self.columns[column];
468 for (index, row) in self.rows.iter_mut().enumerate() {
469 let mut qualified = true;
470 let mut converted = None;
471 let mut convert_to = None;
472 if let Some(value) = row.get_cell_value(&column.name) {
473 if let Some(ttype) = limiter.is_convertible(value) {
475 converted.replace(Value::from_str(&value.to_string(), ttype)?);
476 convert_to = Some(ttype);
477 }
478
479 if !limiter.qualify(converted.as_ref().unwrap_or(value)) {
481 qualified = false;
482 convert_to = None;
483 if panic {
484 return Err(DcsvError::InvalidCellData(format!(
485 "Cell {},{} doesn't match limiter's qualification",
486 index, column.name
487 )));
488 }
489 }
490 } else {
491 return Err(DcsvError::InvalidRowData(
492 "Failed to get row data while setting limiter".to_string(),
493 ));
494 }
495
496 if let Some(ttype) = convert_to {
497 row.change_cell_type(&column.name, ttype)?;
498 } else if !qualified && !panic {
499 row.update_cell_value(
503 &column.name,
504 limiter
505 .get_default()
506 .unwrap_or(&Value::empty(limiter.get_type()))
507 .clone(),
508 );
509 }
510 }
511 column.set_limiter(limiter.clone());
512 Ok(())
513 }
514
515 pub fn qualify(&self, column: usize, limiter: &ValueLimiter) -> DcsvResult<Vec<&Row>> {
517 let mut rows = vec![];
518 let column = &self.columns[column];
519 for row in &self.rows {
520 if let Some(value) = row.get_cell_value(&column.name) {
521 if limiter.qualify(value) {
523 rows.push(row)
524 }
525 } else {
526 return Err(DcsvError::InvalidRowData(
527 "Failed to get row data while qualifying".to_string(),
528 ));
529 }
530 }
531 Ok(rows)
532 }
533
534 pub fn qualify_multiple(
536 &self,
537 qualifiers: Vec<(usize, &ValueLimiter)>,
538 ) -> DcsvResult<Vec<&Row>> {
539 let mut rows = vec![];
540 'outer: for row in &self.rows {
542 for (column, limiter) in &qualifiers {
544 let column = &self.columns[*column];
545 if let Some(value) = row.get_cell_value(&column.name) {
546 if !limiter.qualify(value) {
548 continue 'outer;
549 }
550 } else {
551 return Err(DcsvError::InvalidRowData(
552 "Failed to get row data while qualifying".to_string(),
553 ));
554 }
555 }
556
557 rows.push(row);
559 }
560 Ok(rows)
561 }
562
563 pub fn export_schema(&self) -> String {
573 let mut schema = format!("{}\n", SCHEMA_HEADER);
574 for col in &self.columns {
575 let mut line = col.name.clone() + ",";
576 let limiter = &col.limiter;
577 line.push_str(&limiter.get_type().to_string());
578 line.push(',');
579 line.push_str(
580 &limiter
581 .get_default()
582 .map(|s| s.to_string())
583 .unwrap_or_default(),
584 );
585 line.push(',');
586 line.push_str(
587 &limiter
588 .get_variant()
589 .map(|s| s.iter().map(|s| s.to_string()).collect::<Vec<String>>())
590 .unwrap_or_default()
591 .join(" "),
592 );
593 line.push(',');
594 line.push_str(
595 &limiter
596 .get_pattern()
597 .map(|s| s.to_string())
598 .unwrap_or_default(),
599 );
600
601 schema.push_str(&(line + "\n"));
602 }
603 schema
604 }
605
606 pub fn try_get_column_index(&self, src: &str) -> Option<usize> {
612 let column_index = match src.parse::<usize>() {
613 Err(_) => self.columns.iter().position(|c| c.name == src),
614 Ok(index) => {
615 if index < self.get_column_count() {
616 Some(index)
617 } else {
618 None
619 }
620 }
621 };
622 column_index
623 }
624
625 fn is_valid_cell_coordinate(&self, x: usize, y: usize) -> bool {
631 if x < self.get_row_count() && y < self.get_column_count() {
632 return true;
633 }
634
635 false
636 }
637
638 fn get_column_if_valid(&self, x: usize, y: usize) -> DcsvResult<&Column> {
640 if !self.is_valid_cell_coordinate(x, y) {
641 return Err(DcsvError::OutOfRangeError);
642 }
643 let key_column = self.columns.get(y).unwrap();
646 Ok(key_column)
647 }
648
649 fn is_valid_column_data(&self, column: usize, value: &Value) -> DcsvResult<()> {
651 if let Some(col) = self.columns.get(column) {
652 if col.limiter.qualify(value) {
653 Ok(())
654 } else {
655 Err(DcsvError::InvalidCellData(
656 "Given cell data failed to match limiter's restriction".to_string(),
657 ))
658 }
659 } else {
660 Err(DcsvError::InvalidRowData(format!(
661 "Given column index \"{}\" doesn't exist",
662 column
663 )))
664 }
665 }
666
667 fn check_row_length(&self, values: &[Value]) -> DcsvResult<()> {
669 match self.get_column_count().cmp(&values.len()) {
670 Ordering::Equal => (),
671 Ordering::Less | Ordering::Greater => {
672 return Err(DcsvError::InvalidRowData(format!(
673 r#"Given row length is "{}" while columns length is "{}""#,
674 values.len(),
675 self.get_column_count()
676 )))
677 }
678 }
679 Ok(())
680 }
681
682 pub fn get_iterator(&self) -> std::vec::IntoIter<&Value> {
686 let columns = &self.columns;
687 let mut iterate = vec![];
688 for row in &self.rows {
689 iterate.extend(row.get_iterator(columns));
690 }
691 iterate.into_iter()
692 }
693
694 pub fn get_row_iterator(&self, row_index: usize) -> DcsvResult<std::vec::IntoIter<&Value>> {
698 let columns = &self.columns;
699 Ok(self
700 .rows
701 .get(row_index)
702 .ok_or(DcsvError::OutOfRangeError)?
703 .get_iterator(columns))
704 }
705
706 }
708
709impl std::fmt::Display for VirtualData {
713 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
714 let mut csv_src = String::new();
715 let column_row = self
716 .columns
717 .iter()
718 .map(|c| c.name.as_str())
719 .collect::<Vec<&str>>()
720 .join(",")
721 + "\n";
722 csv_src.push_str(&column_row);
723
724 let columns = self
725 .columns
726 .iter()
727 .map(|col| col.name.as_str())
728 .collect::<Vec<&str>>();
729 for row in &self.rows {
730 let row_value = columns
731 .iter()
732 .map(|name| {
733 row.get_cell_value(name)
734 .unwrap_or(&Value::Text(String::new()))
735 .to_string()
736 })
737 .collect::<Vec<String>>()
738 .join(",")
739 + "\n";
740
741 csv_src.push_str(&row_value);
742 }
743 csv_src.pop();
745 write!(f, "{}", csv_src)
746 }
747}
748
749#[derive(Clone, Debug)]
753pub struct Column {
754 pub name: String,
755 pub column_type: ValueType,
756 pub limiter: ValueLimiter,
757}
758
759impl Column {
760 pub fn empty(name: &str) -> Self {
762 Self {
763 name: name.to_string(),
764 column_type: ValueType::Text,
765 limiter: ValueLimiter::default(),
766 }
767 }
768
769 pub fn new(name: &str, column_type: ValueType, limiter: Option<ValueLimiter>) -> Self {
771 Self {
772 name: name.to_string(),
773 column_type,
774 limiter: limiter.unwrap_or_default(),
775 }
776 }
777
778 pub fn get_name(&self) -> &str {
780 &self.name
781 }
782
783 pub fn get_column_type(&self) -> &ValueType {
785 &self.column_type
786 }
787
788 pub fn rename(&mut self, new_name: &str) -> String {
790 std::mem::replace(&mut self.name, new_name.to_string())
791 }
792
793 pub fn set_limiter(&mut self, limiter: ValueLimiter) {
795 self.column_type = limiter.get_type();
796 self.limiter = limiter;
797 }
798
799 pub fn get_default_value(&self) -> Value {
805 if let Some(def) = self.limiter.get_default() {
807 return def.clone();
808 }
809
810 let variant = self.limiter.get_variant();
812 if let Some(vec) = variant {
813 if !vec.is_empty() {
814 return vec[0].clone();
815 }
816 }
817
818 match self.column_type {
820 ValueType::Number => Value::Number(0),
821 ValueType::Text => Value::Text(String::new()),
822 }
823 }
824}
825
826#[derive(Clone, Debug)]
830pub struct Row {
831 pub values: HashMap<String, Value>,
832}
833
834impl Default for Row {
835 fn default() -> Self {
836 Self::new()
837 }
838}
839
840impl Row {
841 pub fn new() -> Self {
843 Self {
844 values: HashMap::new(),
845 }
846 }
847
848 pub fn to_vector(&self, columns: &[Column]) -> DcsvResult<Vec<&Value>> {
852 let mut acc = Vec::default();
853 for col in columns {
854 acc.push(self.values.get(&col.name).ok_or_else(|| {
855 DcsvError::InvalidColumn(
856 "Given column was not present thus cannot construct row vector".to_string(),
857 )
858 })?);
859 }
860 Ok(acc)
861 }
862
863 pub fn to_string(&self, columns: &[Column]) -> DcsvResult<String> {
868 let mut acc = String::new();
869 for col in columns {
870 acc.push_str(
871 &self
872 .values
873 .get(&col.name)
874 .ok_or_else(|| {
875 DcsvError::InvalidColumn(
876 "Given column was not present thus cannot construct row string"
877 .to_string(),
878 )
879 })?
880 .to_string(),
881 );
882 acc.push(',');
883 }
884 acc.pop(); Ok(acc)
886 }
887
888 pub fn rename_column(&mut self, name: &str, new_name: &str) {
893 let previous = self.values.remove(name);
894
895 if let Some(prev) = previous {
896 self.values.insert(new_name.to_string(), prev);
897 }
898 }
899
900 pub fn insert_cell(&mut self, key: &str, value: Value) {
902 self.values.insert(key.to_string(), value);
903 }
904
905 pub fn get_cell_value(&self, key: &str) -> Option<&Value> {
907 self.values.get(key)
908 }
909
910 pub fn update_cell_value(&mut self, key: &str, value: Value) {
914 if let Some(v) = self.values.get_mut(key) {
915 *v = value;
916 }
917 }
918
919 pub fn change_cell_type(&mut self, key: &str, target_type: ValueType) -> DcsvResult<()> {
924 if let Some(v) = self.values.get_mut(key) {
925 match v {
926 Value::Text(t) => {
927 if target_type == ValueType::Number {
928 if t.is_empty() {
930 *v = Value::Number(0);
931 return Ok(());
932 }
933
934 *v = Value::Number(t.parse::<isize>().map_err(|_| {
935 DcsvError::InvalidCellData(format!(
936 "\"{}\" is not a valid value to be converted to type : \"{}\"",
937 t, target_type
938 ))
939 })?);
940 }
941 }
942 Value::Number(n) => {
943 if target_type == ValueType::Text {
944 *v = Value::Text(n.to_string());
945 }
946 }
947 }
948 }
949 Ok(())
950 }
951
952 pub fn remove_cell(&mut self, key: &str) {
954 self.values.remove(key);
955 }
956
957 pub fn get_iterator(&self, columns: &[Column]) -> std::vec::IntoIter<&Value> {
959 let mut iterate = vec![];
960 for col in columns {
961 if let Some(value) = self.values.get(&col.name) {
962 iterate.push(value);
963 }
964 }
965 iterate.into_iter()
966 }
967}
968
969#[derive(Debug)]
973pub struct ReadOnlyData {
974 pub columns: Vec<Column>,
975 pub rows: Vec<Vec<Value>>,
976}
977
978impl From<&VirtualData> for ReadOnlyData {
979 fn from(data: &VirtualData) -> Self {
980 let mut rows: Vec<Vec<Value>> = vec![];
981 for row in &data.rows {
982 let mut static_row: Vec<Value> = vec![];
983 for col in &data.columns {
984 static_row.push(row.get_cell_value(&col.name).unwrap().clone())
985 }
986 rows.push(static_row);
987 }
988 Self {
989 columns: data.columns.clone(),
990 rows,
991 }
992 }
993}
994
995#[derive(Debug)]
1000pub struct ReadOnlyDataRef<'data> {
1001 pub columns: Vec<&'data Column>,
1002 pub rows: Vec<Vec<&'data Value>>,
1003}
1004
1005impl<'data> ReadOnlyDataRef<'data> {
1006 pub fn to_owned(&self) -> ReadOnlyData {
1010 ReadOnlyData {
1011 columns: self.columns.iter().map(|&c| c.clone()).collect::<Vec<_>>(),
1012 rows: self
1013 .rows
1014 .iter()
1015 .map(|vv| vv.iter().map(|&v| v.clone()).collect::<Vec<_>>())
1016 .collect::<Vec<Vec<_>>>(),
1017 }
1018 }
1019}
1020
1021impl<'data> From<&'data VirtualData> for ReadOnlyDataRef<'data> {
1022 fn from(data: &'data VirtualData) -> Self {
1023 let mut rows: Vec<Vec<&'data Value>> = vec![];
1024 for row in &data.rows {
1025 let mut static_row: Vec<&'data Value> = vec![];
1026 for col in &data.columns {
1027 static_row.push(row.get_cell_value(&col.name).unwrap())
1028 }
1029 rows.push(static_row);
1030 }
1031 Self {
1032 columns: data.columns.iter().collect(),
1033 rows,
1034 }
1035 }
1036}