pharetra/
table.rs

1use std::error::Error;
2use std::fmt;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum TableError {
6    InvalidNumberOfColumns,
7    InvalidNumberOfColumnNames,
8    InvalidNumberOfElements,
9}
10
11impl Error for TableError {}
12impl fmt::Display for TableError {
13    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14        write!(f, "C3dParseError: {:?}", self)
15    }
16}
17
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
19pub enum Order {
20    #[default]
21    RowMajor,
22    ColumnMajor,
23}
24
25impl Order {
26    fn swap(&mut self) {
27        *self = match *self {
28            Order::RowMajor => Order::ColumnMajor,
29            Order::ColumnMajor => Order::RowMajor,
30        }
31    }
32}
33
34pub struct Table<T> {
35    col_names: Vec<String>,
36    descriptions: Vec<String>,
37    data: Vec<T>,
38    num_cols: usize,
39    num_rows: usize,
40    order: Order,
41}
42
43impl<T> Table<T> where T: Default + Clone + Copy {
44    pub fn new() -> Self {
45        Self {
46            col_names: Vec::new(),
47            descriptions: Vec::new(),
48            data: Vec::new(),
49            num_cols: 0,
50            num_rows: 0,
51            order: Order::RowMajor,
52        }
53    }
54
55    pub fn new_sized(
56        num_cols: usize,
57        num_rows: usize,
58        col_names: Vec<String>,
59    ) -> Result<Self, TableError> {
60        if col_names.len() != num_cols {
61            return Err(TableError::InvalidNumberOfColumnNames);
62        }
63        let data = vec![T::default(); num_cols * num_rows];
64        Ok(Self {
65            col_names,
66            descriptions: Vec::from_iter("".repeat(num_cols).split(';').map(|s| s.to_string())),
67            data,
68            num_cols,
69            num_rows,
70            order: Order::default(),
71        })
72    }
73
74    pub fn from_vec(
75        data: Vec<T>,
76        num_cols: usize,
77        col_names: Vec<String>,
78    ) -> Result<Self, TableError> {
79        if data.len() % num_cols != 0 {
80            return Err(TableError::InvalidNumberOfColumns);
81        }
82        if col_names.len() != num_cols {
83            return Err(TableError::InvalidNumberOfColumnNames);
84        }
85        let length = data.len();
86        Ok(Self {
87            col_names,
88            descriptions: Vec::from_iter("".repeat(num_cols).split(';').map(|s| s.to_string())),
89            data,
90            num_cols,
91            num_rows: length / num_cols,
92            order: Order::default(),
93        })
94    }
95
96    pub fn from_vec_with_order(
97        data: Vec<T>,
98        num_cols: usize,
99        col_names: Vec<String>,
100        order: Order,
101    ) -> Result<Self, TableError> {
102        if data.len() % num_cols != 0 {
103            return Err(TableError::InvalidNumberOfColumns);
104        }
105        let length = data.len();
106        Ok(Self {
107            col_names,
108            descriptions: Vec::from_iter("".repeat(num_cols).split(';').map(|s| s.to_string())),
109            data,
110            num_cols,
111            num_rows: length / num_cols,
112            order,
113        })
114    }
115
116    pub fn col(&self, col: usize) -> Option<&[T]> {
117        if col >= self.num_cols {
118            return None;
119        }
120        let mut col = col;
121        if self.order == Order::ColumnMajor {
122            col = col * self.num_rows;
123        }
124        Some(&self.data[col..col + self.num_rows])
125    }
126
127    pub fn col_mut(&mut self, col: usize) -> Option<&mut [T]> {
128        if col >= self.num_cols {
129            return None;
130        }
131        let mut col = col;
132        if self.order == Order::ColumnMajor {
133            col = col * self.num_rows;
134        }
135        Some(&mut self.data[col..col + self.num_rows])
136    }
137
138    pub fn col_name(&self, col: usize) -> Option<&str> {
139        if col >= self.num_cols {
140            return None;
141        }
142        self.col_names.get(col).map(|s| s.as_str())
143    }
144
145    pub fn col_name_mut(&mut self, col: usize) -> Option<&mut String> {
146        if col >= self.num_cols {
147            return None;
148        }
149        self.col_names.get_mut(col)
150    }
151
152    pub fn col_description(&self, col: usize) -> Option<&str> {
153        if col >= self.num_cols {
154            return None;
155        }
156        self.descriptions.get(col).map(|s| s.as_str())
157    }
158
159    pub fn col_description_mut(&mut self, col: usize) -> Option<&mut String> {
160        if col >= self.num_cols {
161            return None;
162        }
163        self.descriptions.get_mut(col)
164    }
165
166    pub fn col_names(&self) -> &[String] {
167        &self.col_names
168    }
169
170    pub fn col_names_mut(&mut self) -> &mut [String] {
171        &mut self.col_names
172    }
173
174    pub fn col_descriptions(&self) -> &[String] {
175        &self.descriptions
176    }
177
178    pub fn col_descriptions_mut(&mut self) -> &mut [String] {
179        &mut self.descriptions
180    }
181
182    pub fn row(&self, row: usize) -> Option<&[T]> {
183        if row >= self.num_rows {
184            return None;
185        }
186        let mut row = row;
187        if self.order == Order::RowMajor {
188            row = row * self.num_cols;
189        }
190        Some(&self.data[row..row + self.num_cols])
191    }
192
193    pub fn row_mut(&mut self, row: usize) -> Option<&mut [T]> {
194        if row >= self.num_rows {
195            return None;
196        }
197        let mut row = row;
198        if self.order == Order::RowMajor {
199            row = row * self.num_cols;
200        }
201        Some(&mut self.data[row..row + self.num_cols])
202    }
203
204    pub fn num_cols(&self) -> usize {
205        self.num_cols
206    }
207
208    pub fn num_rows(&self) -> usize {
209        self.num_rows
210    }
211
212    pub fn order(&self) -> Order {
213        self.order
214    }
215
216    pub fn transpose(&mut self) {
217        self.order.swap();
218        std::mem::swap(&mut self.num_cols, &mut self.num_rows);
219    }
220
221    pub fn into_vec(self) -> Vec<T> {
222        self.data
223    }
224
225    pub fn into_vec_with_names(self) -> (Vec<T>, Vec<String>) {
226        (self.data, self.col_names)
227    }
228
229    pub fn col_by_name(&self, name: &str) -> Option<&[T]> {
230        self.col_names
231            .iter()
232            .position(|s| s == name)
233            .and_then(|i| self.col(i))
234    }
235
236    pub fn col_by_name_mut(&mut self, name: &str) -> Option<&mut [T]> {
237        self.col_names
238            .iter()
239            .position(|s| s == name)
240            .and_then(|i| self.col_mut(i))
241    }
242
243    pub fn get(&self, row: usize, col: usize) -> Option<&T> {
244        if row >= self.num_rows || col >= self.num_cols {
245            return None;
246        }
247        let mut row = row;
248        let mut col = col;
249        if self.order == Order::RowMajor {
250            row = row * self.num_cols;
251        } else {
252            col = col * self.num_rows;
253        }
254        Some(&self.data[row + col])
255    }
256
257    pub fn get_mut(&mut self, row: usize, col: usize) -> Option<&mut T> {
258        if row >= self.num_rows || col >= self.num_cols {
259            return None;
260        }
261        let mut row = row;
262        let mut col = col;
263        if self.order == Order::RowMajor {
264            row = row * self.num_cols;
265        } else {
266            col = col * self.num_rows;
267        }
268        Some(&mut self.data[row + col])
269    }
270
271    pub unsafe fn get_unchecked(&self, row: usize, col: usize) -> &T {
272        let mut row = row;
273        let mut col = col;
274        if self.order == Order::RowMajor {
275            row = row * self.num_cols;
276        } else {
277            col = col * self.num_rows;
278        }
279        &self.data[row + col]
280    }
281
282    pub unsafe fn get_unchecked_mut(&mut self, row: usize, col: usize) -> &mut T {
283        let mut row = row;
284        let mut col = col;
285        if self.order == Order::RowMajor {
286            row = row * self.num_cols;
287        } else {
288            col = col * self.num_rows;
289        }
290        &mut self.data[row + col]
291    }
292
293    pub fn set(&mut self, row: usize, col: usize, value: T) -> Option<T> {
294        if row >= self.num_rows || col >= self.num_cols {
295            return None;
296        }
297        let mut row = row;
298        let mut col = col;
299        if self.order == Order::RowMajor {
300            row = row * self.num_cols;
301        } else {
302            col = col * self.num_rows;
303        }
304        Some(std::mem::replace(&mut self.data[row + col], value))
305    }
306
307    pub fn set_col(&mut self, col: usize, col_data: &[T]) -> Option<Vec<T>>
308    where
309        T: Clone,
310    {
311        if col >= self.num_cols || col_data.len() != self.num_rows {
312            return None;
313        }
314        let mut col = col;
315        if self.order == Order::ColumnMajor {
316            col = col * self.num_rows;
317        }
318        Some(
319            std::mem::replace(
320                &mut self.data[col..col + self.num_rows].to_vec(),
321                col_data.to_vec(),
322            )
323            .into_iter()
324            .collect(),
325        )
326    }
327
328    pub fn set_row(&mut self, row: usize, row_data: &[T]) -> Option<Vec<T>>
329    where
330        T: Clone,
331    {
332        if row >= self.num_rows || row_data.len() != self.num_cols {
333            return None;
334        }
335        let mut row = row;
336        if self.order == Order::RowMajor {
337            row = row * self.num_cols;
338        }
339        Some(
340            std::mem::replace(
341                &mut self.data[row..row + self.num_cols].to_vec(),
342                row_data.to_vec(),
343            )
344            .into_iter()
345            .collect(),
346        )
347    }
348
349    pub fn set_col_by_name(&mut self, name: &str, col_data: &[T]) -> Option<Vec<T>>
350    where
351        T: Clone,
352    {
353        self.col_names
354            .iter()
355            .position(|s| s == name)
356            .and_then(|i| self.set_col(i, col_data))
357    }
358
359    pub fn set_col_name(&mut self, col: usize, name: String) -> Option<String> {
360        if col >= self.num_cols {
361            return None;
362        }
363        Some(std::mem::replace(&mut self.col_names[col], name))
364    }
365
366    pub fn set_col_description(&mut self, col: usize, description: String) -> Option<String> {
367        if col >= self.num_cols {
368            return None;
369        }
370        Some(std::mem::replace(&mut self.descriptions[col], description))
371    }
372
373    pub fn set_col_description_by_name(
374        &mut self,
375        name: &str,
376        description: String,
377    ) -> Option<String> {
378        self.col_names
379            .iter()
380            .position(|s| s == name)
381            .and_then(|i| self.set_col_description(i, description))
382    }
383
384    pub fn iter(&self) -> impl Iterator<Item = &T> {
385        self.data.iter()
386    }
387
388    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
389        self.data.iter_mut()
390    }
391
392    pub fn iter_row(&self, row: usize) -> Option<impl Iterator<Item = &T>> {
393        if row >= self.num_rows {
394            return None;
395        }
396        let mut row = row;
397        if self.order == Order::RowMajor {
398            row = row * self.num_cols;
399        }
400        Some(self.data[row..row + self.num_cols].iter())
401    }
402
403    pub fn iter_row_mut(&mut self, row: usize) -> Option<impl Iterator<Item = &mut T>> {
404        if row >= self.num_rows {
405            return None;
406        }
407        let mut row = row;
408        if self.order == Order::RowMajor {
409            row = row * self.num_cols;
410        }
411        Some(self.data[row..row + self.num_cols].iter_mut())
412    }
413
414    pub fn iter_col(&self, col: usize) -> Option<impl Iterator<Item = &T>> {
415        if col >= self.num_cols {
416            return None;
417        }
418        let mut col = col;
419        if self.order == Order::ColumnMajor {
420            col = col * self.num_rows;
421        }
422        Some(self.data[col..col + self.num_rows].iter())
423    }
424
425    pub fn iter_col_mut(&mut self, col: usize) -> Option<impl Iterator<Item = &mut T>> {
426        if col >= self.num_cols {
427            return None;
428        }
429        let mut col = col;
430        if self.order == Order::ColumnMajor {
431            col = col * self.num_rows;
432        }
433        Some(self.data[col..col + self.num_rows].iter_mut())
434    }
435
436    pub fn iter_col_by_name(&self, name: &str) -> Option<impl Iterator<Item = &T>> {
437        self.col_names
438            .iter()
439            .position(|s| s == name)
440            .and_then(|i| self.iter_col(i))
441    }
442
443    pub fn iter_col_by_name_mut(&mut self, name: &str) -> Option<impl Iterator<Item = &mut T>> {
444        self.col_names
445            .iter()
446            .position(|s| s == name)
447            .and_then(|i| self.iter_col_mut(i))
448    }
449
450    pub fn push_col(&mut self, name: String, col: Vec<T>) -> Result<(), TableError> {
451        if col.len() != self.num_rows {
452            return Err(TableError::InvalidNumberOfElements);
453        }
454        self.col_names.push(name);
455        self.data.extend(col);
456        self.num_cols += 1;
457        self.descriptions.push("".to_string());
458        Ok(())
459    }
460
461    pub fn push_row(&mut self, row: Vec<T>) -> Result<(), TableError> {
462        if row.len() != self.num_cols {
463            return Err(TableError::InvalidNumberOfElements);
464        }
465        self.data.extend(row);
466        self.num_rows += 1;
467        Ok(())
468    }
469
470    pub fn remove_col(&mut self, col: usize) -> Option<Vec<T>> {
471        if col >= self.num_cols {
472            return None;
473        }
474        let mut col = col;
475        if self.order == Order::ColumnMajor {
476            col = col * self.num_rows;
477        }
478        let out_col = self.data.drain(col..col + self.num_rows);
479        self.col_names.remove(col);
480        self.num_cols -= 1;
481        self.descriptions.remove(col);
482        Some(out_col.collect())
483    }
484
485    pub fn remove_row(&mut self, row: usize) -> Option<Vec<T>> {
486        if row >= self.num_rows {
487            return None;
488        }
489        let mut row = row;
490        if self.order == Order::RowMajor {
491            row = row * self.num_cols;
492        }
493        self.num_rows -= 1;
494        Some(self.data.drain(row..row + self.num_cols).collect())
495    }
496}
497