htable/
lib.rs

1#[derive(Debug, Clone)]
2pub enum HTableItems {
3    IntegerItem(i64),
4    FloatItem(f64),
5    FieldItem(String),
6    BooleanItem(bool),
7}
8
9#[derive(Debug)]
10pub struct HTableData<'a> {
11    items: Vec<&'a HTableItems>,
12}
13
14impl<'a> HTableData<'a> {
15    pub fn new(items: Vec<&'a HTableItems>) -> Self {
16        HTableData {
17            items
18        }
19    }
20
21    /// Get the items as an owned variable
22    pub fn items(self) -> Vec<&'a HTableItems> {
23        self.items
24    }
25}
26
27
28#[derive(Debug)]
29pub struct IterHTableData<'a> {
30    curr_idx: usize,
31    items: Vec<&'a HTableItems>,
32}
33
34impl<'a> IterHTableData<'a> {
35    pub fn new(items: Vec<&'a HTableItems>) -> Self {
36        IterHTableData {
37            curr_idx: 0,
38            items
39        }
40    }
41}
42
43impl<'a> Iterator for IterHTableData<'a> {
44    type Item = &'a HTableItems;
45
46    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
47        if self.curr_idx >= self.items.len(){
48            None
49        } else {
50            self.curr_idx += 1;
51            Some(self.items[self.curr_idx - 1])
52        }
53    }
54}
55
56#[derive(Debug, Clone)]
57pub struct HTable(Vec<Vec<HTableItems>>);
58
59impl HTable {
60    pub fn new() -> Self {
61        HTable(Vec::new())
62    }
63
64    pub fn append_row(&mut self, row: Vec<HTableItems>) {
65        if self.0.len() == 0 {
66            // table is uninitialised
67            for row_data in row {
68                self.0.push(vec![row_data]);
69            }
70        } else if self.0.len() != row.len() {
71            panic!("The number of columns in the row you are trying to add does not match the number of columns in the table")
72        } else {
73            for col_idx in 0..row.len() {
74                let row_result = &row[col_idx];
75                let table_col = &mut self.0[col_idx];
76
77                match (row_result, table_col.as_slice()) {
78                    (HTableItems::IntegerItem(_), [HTableItems::IntegerItem(_)])
79                    | (HTableItems::FloatItem(_), [HTableItems::FloatItem(_)])
80                    | (HTableItems::FieldItem(_), [HTableItems::FieldItem(_)])
81                    | (HTableItems::BooleanItem(_), [HTableItems::BooleanItem(_)]) => {
82                        table_col.push(row_result.clone());
83                    }
84                    _ => panic!("Mismatched types between row and table"),
85                }
86            }
87        }
88    }
89
90    pub fn number_of_columns(&self) -> usize {
91        self.0.len()
92    }
93
94    pub fn number_of_rows(&self) -> usize {
95        self.0[0].len()
96    }
97
98    pub fn get_row(&self, row: usize) -> Option<HTableData> {
99        let mut row_data = Vec::new();
100
101        if row < self.number_of_rows() {
102            for c_inx in 0..self.number_of_columns() {
103                row_data.push(&self.0[c_inx][row]);
104            }
105
106            Some(HTableData::new(row_data))
107        }else{
108            None
109        }
110    }
111
112    pub fn get_col(&self, col: usize) -> Option<HTableData> {
113        let mut col_data = Vec::new();
114
115        if col < self.number_of_columns() {
116            for r_idx in 0..self.number_of_rows() {
117                col_data.push(&self.0[col][r_idx]);
118            }
119
120            Some(HTableData::new(col_data))
121        }else{
122            None
123        }
124    }
125
126    pub fn iter_row(&self, row: usize) -> Option<impl Iterator<Item=&HTableItems>> {
127        let mut row_data = Vec::new();
128
129        if row < self.number_of_rows() {
130            for c_inx in 0..self.number_of_columns() {
131                row_data.push(&self.0[c_inx][row]);
132            }
133
134            Some(IterHTableData::new(row_data))
135        }else{
136            None
137        }
138    }
139
140    pub fn iter_col(&self, col: usize) -> Option<impl Iterator<Item=&HTableItems>> {
141        let mut col_data = Vec::new();
142
143        if col < self.number_of_columns() {
144            for r_idx in 0..self.number_of_rows() {
145                col_data.push(&self.0[col][r_idx]);
146            }
147
148            Some(IterHTableData::new(col_data))
149        }else{
150            None
151        }
152    }
153}
154
155// todo: write tests!