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