dypdl/table_data.rs
1use crate::table;
2use crate::util::ModelErr;
3use crate::variable_type::Element;
4use approx::{AbsDiffEq, RelativeEq};
5use rustc_hash::{FxHashMap, FxHashSet};
6use std::collections::hash_map::Entry;
7use std::marker::PhantomData;
8
9macro_rules! define_table_handle {
10 ($x:ident) => {
11 /// A struct wrapping the id of a table.
12 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
13 pub struct $x<T>(usize, PhantomData<T>);
14
15 impl<T> $x<T> {
16 /// Returns the id
17 pub fn id(&self) -> usize {
18 self.0
19 }
20 }
21 };
22}
23
24define_table_handle!(Table1DHandle);
25define_table_handle!(Table2DHandle);
26define_table_handle!(Table3DHandle);
27define_table_handle!(TableHandle);
28
29/// Trait for adding and updating tables of constants.
30///
31/// # Examples
32///
33/// ```
34/// use dypdl::prelude::*;
35/// use rustc_hash::FxHashMap;
36///
37/// let mut model = Model::default();
38///
39/// assert!(model.add_table_1d("table_1d", vec![1, 2]).is_ok());
40///
41/// assert!(model.add_table_2d("table_2d", vec![vec![1, 2], vec![3, 4]]).is_ok());
42///
43/// assert!(
44/// model.add_table_3d(
45/// "table_3d",
46/// vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]]
47/// ).is_ok()
48/// );
49///
50/// let map = FxHashMap::from_iter(vec![(vec![0, 0, 0, 0], 1), (vec![1, 1, 1, 1], 2)]);
51/// assert!(
52/// model.add_table("table", map, 0).is_ok()
53/// );
54/// ```
55pub trait TableInterface<T> {
56 /// Adds and returns a 1D table.
57 ///
58 /// # Errors
59 ///
60 /// If the name is already used.
61 fn add_table_1d<U>(&mut self, name: U, v: Vec<T>) -> Result<Table1DHandle<T>, ModelErr>
62 where
63 String: From<U>;
64
65 // Disabled since it conflicts with the simplification of an expression.
66 // /// Set an item in a 1D table.
67 // ///
68 // /// # Errors
69 // ///
70 // /// If the table is not in the model.
71 // fn set_table_1d(&mut self, t: Table1DHandle<T>, x: Element, v: T) -> Result<(), ModelErr>;
72
73 // Disabled since it conflicts with the simplification of an expression.
74 // /// Update a 1D table.
75 // ///
76 // /// # Errors
77 // ///
78 // /// If the table is not in the model.
79 // fn update_table_1d(&mut self, t: Table1DHandle<T>, v: Vec<T>) -> Result<(), ModelErr>;
80
81 /// Adds and returns a 2D table.
82 ///
83 /// # Errors
84 ///
85 /// If the name is already used.
86 fn add_table_2d<U>(&mut self, name: U, v: Vec<Vec<T>>) -> Result<Table2DHandle<T>, ModelErr>
87 where
88 String: From<U>;
89
90 // Disabled since it conflicts with the simplification of an expression.
91 // /// Set an item in a 2D table.
92 // ///
93 // /// # Errors
94 // ///
95 // /// If the table is not in the model.
96 // fn set_table_2d(
97 // &mut self,
98 // t: Table2DHandle<T>,
99 // x: Element,
100 // y: Element,
101 // v: T,
102 // ) -> Result<(), ModelErr>;
103
104 // Disabled since it conflicts with the simplification of an expression.
105 // /// Update a 2D table.
106 // ///
107 // /// # Errors
108 // ///
109 // /// If the table is not in the model.
110 // fn update_table_2d(&mut self, t: Table2DHandle<T>, v: Vec<Vec<T>>) -> Result<(), ModelErr>;
111
112 /// Adds and returns a 3D table.
113 ///
114 /// # Errors
115 ///
116 /// If the name is already used.
117 fn add_table_3d<U>(
118 &mut self,
119 name: U,
120 v: Vec<Vec<Vec<T>>>,
121 ) -> Result<Table3DHandle<T>, ModelErr>
122 where
123 String: From<U>;
124
125 // Disabled since it conflicts with the simplification of an expression.
126 // /// Set an item in a 3D table.
127 // ///
128 // /// # Errors
129 // ///
130 // /// If the table is not in the model.
131 // fn set_table_3d(
132 // &mut self,
133 // t: Table3DHandle<T>,
134 // x: Element,
135 // y: Element,
136 // z: Element,
137 // v: T,
138 // ) -> Result<(), ModelErr>;
139
140 // Disabled since it conflicts with the simplification of an expression.
141 // /// Update a 3D table.
142 // ///
143 // /// # Errors
144 // ///
145 // /// If the table is not in the model.
146 // fn update_table_3d(&mut self, t: Table3DHandle<T>, v: Vec<Vec<Vec<T>>>)
147 // -> Result<(), ModelErr>;
148
149 /// Adds and returns a 3D table.
150 ///
151 /// # Errors
152 ///
153 /// If the name is already used.
154 fn add_table<U>(
155 &mut self,
156 name: U,
157 map: FxHashMap<Vec<Element>, T>,
158 default: T,
159 ) -> Result<TableHandle<T>, ModelErr>
160 where
161 String: From<U>;
162
163 // Disabled since it conflicts with the simplification of an expression.
164 // /// Set an item in a table.
165 // ///
166 // /// # Errors
167 // ///
168 // /// If the table is not in the model.
169 // fn set_table(&mut self, t: TableHandle<T>, key: Vec<Element>, v: T) -> Result<(), ModelErr>;
170
171 // Disabled since it conflicts with the simplification of an expression.
172 // /// Set the default value of a table.
173 // ///
174 // /// # Errors
175 // ///
176 // /// If the table is not in the model.
177 // fn set_default(&mut self, t: TableHandle<T>, default: T) -> Result<(), ModelErr>;
178
179 // Disabled since it conflicts with the simplification of an expression.
180 // /// Update a table.
181 // ///
182 // /// # Errors
183 // ///
184 // /// If the table is not in the model.
185 // fn update_table(
186 // &mut self,
187 // t: TableHandle<T>,
188 // map: FxHashMap<Vec<Element>, T>,
189 // default: T,
190 // ) -> Result<(), ModelErr>;
191}
192
193/// Tables of constants havint a particular type.
194#[derive(Debug, PartialEq, Clone, Default)]
195pub struct TableData<T> {
196 /// Map from a name to a constant.
197 pub name_to_constant: FxHashMap<String, T>,
198 /// 1-dimensional tables.
199 pub tables_1d: Vec<table::Table1D<T>>,
200 /// Map from a name to a 1-dimensional table.
201 pub name_to_table_1d: FxHashMap<String, usize>,
202 /// 2-dimensional tables.
203 pub tables_2d: Vec<table::Table2D<T>>,
204 /// Map from a name to a 2-dimensional table.
205 pub name_to_table_2d: FxHashMap<String, usize>,
206 /// 3-dimensional tables.
207 pub tables_3d: Vec<table::Table3D<T>>,
208 /// Map from a name to a 3-dimensional table.
209 pub name_to_table_3d: FxHashMap<String, usize>,
210 /// Multi-dimensional tables implemented by a map.
211 pub tables: Vec<table::Table<T>>,
212 /// Map from a name to a multi-dimensional table.
213 pub name_to_table: FxHashMap<String, usize>,
214}
215
216impl<T> TableInterface<T> for TableData<T> {
217 fn add_table_1d<U>(&mut self, name: U, v: Vec<T>) -> Result<Table1DHandle<T>, ModelErr>
218 where
219 String: From<U>,
220 {
221 let name = String::from(name);
222 if v.is_empty() {
223 return Err(ModelErr::new(format!("1D table `{name}` is empty")));
224 }
225 match self.name_to_table_1d.entry(name) {
226 Entry::Vacant(e) => {
227 let id = self.tables_1d.len();
228 self.tables_1d.push(table::Table1D::new(v));
229 e.insert(id);
230 Ok(Table1DHandle(id, PhantomData))
231 }
232 Entry::Occupied(e) => Err(ModelErr::new(format!(
233 "1D table `{key}` already exists",
234 key = e.key()
235 ))),
236 }
237 }
238
239 // fn set_table_1d(&mut self, t: Table1DHandle<T>, x: Element, v: T) -> Result<(), ModelErr> {
240 // self.check_table_1d(t.id())?;
241 // self.tables_1d[t.id()].set(x, v);
242 // Ok(())
243 // }
244
245 // fn update_table_1d(&mut self, t: Table1DHandle<T>, v: Vec<T>) -> Result<(), ModelErr> {
246 // self.check_table_1d(t.id())?;
247 // if v.is_empty() {
248 // return Err(ModelErr::new(format!(
249 // "1D table with id `{id}` is updated to be empty",
250 // id = t.id()
251 // )));
252 // }
253 // self.tables_1d[t.id()].update(v);
254 // Ok(())
255 // }
256
257 fn add_table_2d<U>(&mut self, name: U, v: Vec<Vec<T>>) -> Result<Table2DHandle<T>, ModelErr>
258 where
259 String: From<U>,
260 {
261 let name = String::from(name);
262 if v.is_empty() || v[0].is_empty() {
263 return Err(ModelErr::new(format!("2D table `{name}` is empty")));
264 }
265 match self.name_to_table_2d.entry(name) {
266 Entry::Vacant(e) => {
267 let id = self.tables_2d.len();
268 self.tables_2d.push(table::Table2D::new(v));
269 e.insert(id);
270 Ok(Table2DHandle(id, PhantomData))
271 }
272 Entry::Occupied(e) => Err(ModelErr::new(format!(
273 "2D table `{key}` already exists",
274 key = e.key()
275 ))),
276 }
277 }
278
279 // fn set_table_2d(
280 // &mut self,
281 // t: Table2DHandle<T>,
282 // x: Element,
283 // y: Element,
284 // v: T,
285 // ) -> Result<(), ModelErr> {
286 // self.check_table_2d(t.id())?;
287 // self.tables_2d[t.id()].set(x, y, v);
288 // Ok(())
289 // }
290
291 // fn update_table_2d(&mut self, t: Table2DHandle<T>, v: Vec<Vec<T>>) -> Result<(), ModelErr> {
292 // self.check_table_2d(t.id())?;
293 // if v.is_empty() || v[0].is_empty() {
294 // return Err(ModelErr::new(format!(
295 // "2D table with id `{id}` is updated to be empty",
296 // id = t.id()
297 // )));
298 // }
299 // self.tables_2d[t.id()].update(v);
300 // Ok(())
301 // }
302
303 fn add_table_3d<U>(
304 &mut self,
305 name: U,
306 v: Vec<Vec<Vec<T>>>,
307 ) -> Result<Table3DHandle<T>, ModelErr>
308 where
309 String: From<U>,
310 {
311 let name = String::from(name);
312 if v.is_empty() || v[0].is_empty() || v[0][0].is_empty() {
313 return Err(ModelErr::new(format!("3D table {name} is empy")));
314 }
315 match self.name_to_table_3d.entry(name) {
316 Entry::Vacant(e) => {
317 let id = self.tables_3d.len();
318 self.tables_3d.push(table::Table3D::new(v));
319 e.insert(id);
320 Ok(Table3DHandle(id, PhantomData))
321 }
322 Entry::Occupied(e) => Err(ModelErr::new(format!(
323 "3D table `{key}` already exists",
324 key = e.key()
325 ))),
326 }
327 }
328
329 // fn set_table_3d(
330 // &mut self,
331 // t: Table3DHandle<T>,
332 // x: Element,
333 // y: Element,
334 // z: Element,
335 // v: T,
336 // ) -> Result<(), ModelErr> {
337 // self.check_table_3d(t.id())?;
338 // self.tables_3d[t.id()].set(x, y, z, v);
339 // Ok(())
340 // }
341
342 // fn update_table_3d(
343 // &mut self,
344 // t: Table3DHandle<T>,
345 // v: Vec<Vec<Vec<T>>>,
346 // ) -> Result<(), ModelErr> {
347 // self.check_table_3d(t.id())?;
348 // if v.is_empty() || v[0].is_empty() || v[0][0].is_empty() {
349 // return Err(ModelErr::new(format!(
350 // "3D table with id `{id}` is updated to be empty",
351 // id = t.id()
352 // )));
353 // }
354 // self.tables_3d[t.id()].update(v);
355 // Ok(())
356 // }
357
358 fn add_table<U>(
359 &mut self,
360 name: U,
361 map: FxHashMap<Vec<Element>, T>,
362 default: T,
363 ) -> Result<TableHandle<T>, ModelErr>
364 where
365 String: From<U>,
366 {
367 let name = String::from(name);
368 match self.name_to_table.entry(name) {
369 Entry::Vacant(e) => {
370 let id = self.tables.len();
371 self.tables.push(table::Table::new(map, default));
372 e.insert(id);
373 Ok(TableHandle(id, PhantomData))
374 }
375 Entry::Occupied(e) => Err(ModelErr::new(format!(
376 "table `{key}` already exists",
377 key = e.key()
378 ))),
379 }
380 }
381
382 // fn set_table(&mut self, t: TableHandle<T>, key: Vec<Element>, v: T) -> Result<(), ModelErr> {
383 // self.check_table(t.id())?;
384 // self.tables[t.id()].set(key, v);
385 // Ok(())
386 // }
387
388 // fn set_default(&mut self, t: TableHandle<T>, default: T) -> Result<(), ModelErr> {
389 // self.check_table(t.id())?;
390 // self.tables[t.id()].set_default(default);
391 // Ok(())
392 // }
393
394 // fn update_table(
395 // &mut self,
396 // t: TableHandle<T>,
397 // map: FxHashMap<Vec<Element>, T>,
398 // default: T,
399 // ) -> Result<(), ModelErr> {
400 // self.check_table(t.id())?;
401 // self.tables[t.id()].update(map, default);
402 // Ok(())
403 // }
404}
405
406impl<T> TableData<T> {
407 /// Returns the set of names used by constants and tables.
408 pub fn get_name_set(&self) -> FxHashSet<String> {
409 let mut name_set = FxHashSet::default();
410 for name in self.name_to_constant.keys() {
411 name_set.insert(name.clone());
412 }
413 for name in self.name_to_table_1d.keys() {
414 name_set.insert(name.clone());
415 }
416 for name in self.name_to_table_2d.keys() {
417 name_set.insert(name.clone());
418 }
419 for name in self.name_to_table_3d.keys() {
420 name_set.insert(name.clone());
421 }
422 for name in self.name_to_table.keys() {
423 name_set.insert(name.clone());
424 }
425 name_set
426 }
427
428 /// Checks if the id of a 1D table is valid.
429 ///
430 /// # Errors
431 ///
432 /// If the id is not used.
433 pub fn check_table_1d(&self, id: usize) -> Result<(), ModelErr> {
434 let n = self.tables_1d.len();
435 if id >= n {
436 Err(ModelErr::new(format!("table 1d id {id} >= #tables ({n})",)))
437 } else {
438 Ok(())
439 }
440 }
441
442 /// Checks if the id of a 2D table is valid.
443 ///
444 /// # Errors
445 ///
446 /// If the id is not used.
447 pub fn check_table_2d(&self, id: usize) -> Result<(), ModelErr> {
448 let n = self.tables_2d.len();
449 if id >= n {
450 Err(ModelErr::new(format!("table 2d id {id} >= #tables ({n})",)))
451 } else {
452 Ok(())
453 }
454 }
455
456 /// Checks if the id of a 3D table is valid.
457 ///
458 /// # Errors
459 ///
460 /// If the id is not used.
461 pub fn check_table_3d(&self, id: usize) -> Result<(), ModelErr> {
462 let n = self.tables_3d.len();
463 if id >= n {
464 Err(ModelErr::new(format!("table 3d id {id} >= #tables ({n})",)))
465 } else {
466 Ok(())
467 }
468 }
469
470 /// Checks if the id of a table is valid.
471 ///
472 /// # Errors
473 ///
474 /// If the id is not used.
475 pub fn check_table(&self, id: usize) -> Result<(), ModelErr> {
476 let n = self.tables.len();
477 if id >= n {
478 Err(ModelErr::new(format!("table id {id} >= #tables ({n})",)))
479 } else {
480 Ok(())
481 }
482 }
483}
484
485impl<T: AbsDiffEq> AbsDiffEq for TableData<T>
486where
487 T::Epsilon: Copy,
488{
489 type Epsilon = T::Epsilon;
490
491 fn default_epsilon() -> T::Epsilon {
492 T::default_epsilon()
493 }
494
495 fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
496 if self.name_to_constant.len() != other.name_to_constant.len() {
497 return false;
498 }
499 for (key, x) in &self.name_to_constant {
500 match other.name_to_constant.get(key) {
501 Some(y) if x.abs_diff_eq(y, epsilon) => {}
502 _ => return false,
503 }
504 }
505 self.name_to_table_1d == other.name_to_table_1d
506 && self.name_to_table_2d == other.name_to_table_2d
507 && self.name_to_table_3d == other.name_to_table_3d
508 && self.name_to_table == other.name_to_table
509 && self
510 .tables_1d
511 .iter()
512 .zip(other.tables_1d.iter())
513 .all(|(x, y)| x.abs_diff_eq(y, epsilon))
514 && self
515 .tables_2d
516 .iter()
517 .zip(other.tables_2d.iter())
518 .all(|(x, y)| x.abs_diff_eq(y, epsilon))
519 && self
520 .tables_3d
521 .iter()
522 .zip(other.tables_3d.iter())
523 .all(|(x, y)| x.abs_diff_eq(y, epsilon))
524 && self
525 .tables
526 .iter()
527 .zip(other.tables.iter())
528 .all(|(x, y)| x.abs_diff_eq(y, epsilon))
529 }
530}
531
532impl<T: RelativeEq> RelativeEq for TableData<T>
533where
534 T::Epsilon: Copy,
535{
536 fn default_max_relative() -> T::Epsilon {
537 T::default_max_relative()
538 }
539
540 fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
541 if self.name_to_constant.len() != other.name_to_constant.len() {
542 return false;
543 }
544 for (key, x) in &self.name_to_constant {
545 match other.name_to_constant.get(key) {
546 Some(y) if x.relative_eq(y, epsilon, max_relative) => {}
547 _ => return false,
548 }
549 }
550 self.name_to_table_1d == other.name_to_table_1d
551 && self.name_to_table_2d == other.name_to_table_2d
552 && self.name_to_table_3d == other.name_to_table_3d
553 && self.name_to_table == other.name_to_table
554 && self
555 .tables_1d
556 .iter()
557 .zip(other.tables_1d.iter())
558 .all(|(x, y)| x.relative_eq(y, epsilon, max_relative))
559 && self
560 .tables_2d
561 .iter()
562 .zip(other.tables_2d.iter())
563 .all(|(x, y)| x.relative_eq(y, epsilon, max_relative))
564 && self
565 .tables_3d
566 .iter()
567 .zip(other.tables_3d.iter())
568 .all(|(x, y)| x.relative_eq(y, epsilon, max_relative))
569 && self
570 .tables
571 .iter()
572 .zip(other.tables.iter())
573 .all(|(x, y)| x.relative_eq(y, epsilon, max_relative))
574 }
575}
576
577#[cfg(test)]
578mod tests {
579 use super::*;
580 use approx::{assert_relative_eq, assert_relative_ne};
581 use table::*;
582
583 #[test]
584 fn add_table_1d_ok() {
585 let mut table_data = TableData::default();
586 let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
587 assert!(t.is_ok());
588 let t = t.unwrap();
589 assert_eq!(t.id(), 0);
590 assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![0, 1])]);
591 let mut name_to_table = FxHashMap::default();
592 name_to_table.insert(String::from("t1"), 0);
593 assert_eq!(table_data.name_to_table_1d, name_to_table);
594 let t = table_data.add_table_1d(String::from("t2"), vec![0, 2]);
595 assert!(t.is_ok());
596 let t = t.unwrap();
597 assert_eq!(t.id(), 1);
598 assert_eq!(
599 table_data.tables_1d,
600 vec![Table1D::new(vec![0, 1]), Table1D::new(vec![0, 2])]
601 );
602 name_to_table.insert(String::from("t2"), 1);
603 assert_eq!(table_data.name_to_table_1d, name_to_table);
604 }
605
606 #[test]
607 fn add_table_1d_err() {
608 let mut table_data = TableData::default();
609 let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
610 assert!(t.is_ok());
611 let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
612 assert!(t.is_err());
613 assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![0, 1])]);
614 let mut name_to_table = FxHashMap::default();
615 name_to_table.insert(String::from("t1"), 0);
616 assert_eq!(table_data.name_to_table_1d, name_to_table);
617 }
618
619 #[test]
620 fn add_table_1d_empty_err() {
621 let mut table_data: TableData<Element> = TableData::default();
622 let t = table_data.add_table_1d(String::from("t1"), vec![]);
623 assert!(t.is_err());
624 assert_eq!(table_data.tables_1d, vec![]);
625 let name_to_table = FxHashMap::default();
626 assert_eq!(table_data.name_to_table_1d, name_to_table);
627 }
628
629 // #[test]
630 // fn set_table_1d_ok() {
631 // let mut table_data = TableData::default();
632 // let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
633 // assert!(t.is_ok());
634 // let t = t.unwrap();
635 // let result = table_data.set_table_1d(t, 0, 1);
636 // assert!(result.is_ok());
637 // assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![1, 1])]);
638 // }
639
640 // #[test]
641 // fn set_table_1d_err() {
642 // let mut table_data = TableData::default();
643 // let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
644 // assert!(t.is_ok());
645
646 // let mut table_data1 = TableData::default();
647 // let t = table_data1.add_table_1d(String::from("t1"), vec![0, 1]);
648 // assert!(t.is_ok());
649 // let t = table_data1.add_table_1d(String::from("t2"), vec![0, 1]);
650 // assert!(t.is_ok());
651 // let t = t.unwrap();
652 // let result = table_data.set_table_1d(t, 0, 1);
653 // assert!(result.is_err());
654 // assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![0, 1])]);
655 // }
656
657 // #[test]
658 // fn update_table_1d_ok() {
659 // let mut table_data = TableData::default();
660 // let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
661 // assert!(t.is_ok());
662 // let t = t.unwrap();
663 // let result = table_data.update_table_1d(t, vec![1, 1]);
664 // assert!(result.is_ok());
665 // assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![1, 1])]);
666 // }
667
668 // #[test]
669 // fn update_table_1d_err() {
670 // let mut table_data = TableData::default();
671 // let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
672 // assert!(t.is_ok());
673
674 // let mut table_data1 = TableData::default();
675 // let t = table_data1.add_table_1d(String::from("t1"), vec![0, 1]);
676 // assert!(t.is_ok());
677 // let t = table_data1.add_table_1d(String::from("t2"), vec![0, 1]);
678 // assert!(t.is_ok());
679 // let t = t.unwrap();
680 // let result = table_data.update_table_1d(t, vec![1, 1]);
681 // assert!(result.is_err());
682 // assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![0, 1])]);
683 // }
684
685 // #[test]
686 // fn update_table_1d_empty_err() {
687 // let mut table_data = TableData::default();
688 // let t = table_data.add_table_1d(String::from("t1"), vec![0, 1]);
689 // assert!(t.is_ok());
690 // let t = t.unwrap();
691 // let result = table_data.update_table_1d(t, vec![]);
692 // assert!(result.is_err());
693 // assert_eq!(table_data.tables_1d, vec![Table1D::new(vec![0, 1])]);
694 // }
695
696 #[test]
697 fn add_table_2d_ok() {
698 let mut table_data = TableData::default();
699 let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
700 assert!(t.is_ok());
701 let t = t.unwrap();
702 assert_eq!(t.id(), 0);
703 assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
704 let mut name_to_table = FxHashMap::default();
705 name_to_table.insert(String::from("t1"), 0);
706 assert_eq!(table_data.name_to_table_2d, name_to_table);
707 let t = table_data.add_table_2d(String::from("t2"), vec![vec![0, 2]]);
708 assert!(t.is_ok());
709 let t = t.unwrap();
710 assert_eq!(t.id(), 1);
711 assert_eq!(
712 table_data.tables_2d,
713 vec![
714 Table2D::new(vec![vec![0, 1]]),
715 Table2D::new(vec![vec![0, 2]])
716 ]
717 );
718 name_to_table.insert(String::from("t2"), 1);
719 assert_eq!(table_data.name_to_table_2d, name_to_table);
720 }
721
722 #[test]
723 fn add_table_2d_err() {
724 let mut table_data = TableData::default();
725 let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
726 assert!(t.is_ok());
727 let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
728 assert!(t.is_err());
729 assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
730 let mut name_to_table = FxHashMap::default();
731 name_to_table.insert(String::from("t1"), 0);
732 assert_eq!(table_data.name_to_table_2d, name_to_table);
733 }
734
735 #[test]
736 fn add_table_2d_empty_1d_err() {
737 let mut table_data: TableData<Element> = TableData::default();
738 let t = table_data.add_table_2d(String::from("t1"), vec![]);
739 assert!(t.is_err());
740 assert_eq!(table_data.tables_2d, vec![]);
741 let name_to_table = FxHashMap::default();
742 assert_eq!(table_data.name_to_table_2d, name_to_table);
743 }
744
745 #[test]
746 fn add_table_2d_empty_2d_err() {
747 let mut table_data: TableData<Element> = TableData::default();
748 let t = table_data.add_table_2d(String::from("t1"), vec![vec![]]);
749 assert!(t.is_err());
750 assert_eq!(table_data.tables_2d, vec![]);
751 let name_to_table = FxHashMap::default();
752 assert_eq!(table_data.name_to_table_2d, name_to_table);
753 }
754
755 // #[test]
756 // fn set_table_2d_ok() {
757 // let mut table_data = TableData::default();
758 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
759 // assert!(t.is_ok());
760 // let t = t.unwrap();
761 // let result = table_data.set_table_2d(t, 0, 0, 1);
762 // assert!(result.is_ok());
763 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![1, 1]])]);
764 // }
765
766 // #[test]
767 // fn set_table_2d_err() {
768 // let mut table_data = TableData::default();
769 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
770 // assert!(t.is_ok());
771
772 // let mut table_data1 = TableData::default();
773 // let t = table_data1.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
774 // assert!(t.is_ok());
775 // let t = table_data1.add_table_2d(String::from("t2"), vec![vec![0, 1]]);
776 // assert!(t.is_ok());
777 // let t = t.unwrap();
778 // let result = table_data.set_table_2d(t, 0, 0, 1);
779 // assert!(result.is_err());
780 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
781 // }
782
783 // #[test]
784 // fn update_table_2d_ok() {
785 // let mut table_data = TableData::default();
786 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
787 // assert!(t.is_ok());
788 // let t = t.unwrap();
789 // let result = table_data.update_table_2d(t, vec![vec![1, 1]]);
790 // assert!(result.is_ok());
791 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![1, 1]])]);
792 // }
793
794 // #[test]
795 // fn update_table_2d_err() {
796 // let mut table_data = TableData::default();
797 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
798 // assert!(t.is_ok());
799
800 // let mut table_data1 = TableData::default();
801 // let t = table_data1.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
802 // assert!(t.is_ok());
803 // let t = table_data1.add_table_2d(String::from("t2"), vec![vec![0, 1]]);
804 // assert!(t.is_ok());
805 // let t = t.unwrap();
806 // let result = table_data.update_table_2d(t, vec![vec![1, 1]]);
807 // assert!(result.is_err());
808 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
809 // }
810
811 // #[test]
812 // fn update_table_2d_empty_1d_ok() {
813 // let mut table_data = TableData::default();
814 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
815 // assert!(t.is_ok());
816 // let t = t.unwrap();
817 // let result = table_data.update_table_2d(t, vec![]);
818 // assert!(result.is_err());
819 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
820 // }
821
822 // #[test]
823 // fn update_table_2d_empty_2d_ok() {
824 // let mut table_data = TableData::default();
825 // let t = table_data.add_table_2d(String::from("t1"), vec![vec![0, 1]]);
826 // assert!(t.is_ok());
827 // let t = t.unwrap();
828 // let result = table_data.update_table_2d(t, vec![vec![]]);
829 // assert!(result.is_err());
830 // assert_eq!(table_data.tables_2d, vec![Table2D::new(vec![vec![0, 1]])]);
831 // }
832
833 #[test]
834 fn add_table_3d_ok() {
835 let mut table_data = TableData::default();
836 let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
837 assert!(t.is_ok());
838 let t = t.unwrap();
839 assert_eq!(t.id(), 0);
840 assert_eq!(
841 table_data.tables_3d,
842 vec![Table3D::new(vec![vec![vec![0, 1]]])]
843 );
844 let mut name_to_table = FxHashMap::default();
845 name_to_table.insert(String::from("t1"), 0);
846 assert_eq!(table_data.name_to_table_3d, name_to_table);
847 let t = table_data.add_table_3d(String::from("t2"), vec![vec![vec![0, 2]]]);
848 assert!(t.is_ok());
849 let t = t.unwrap();
850 assert_eq!(t.id(), 1);
851 assert_eq!(
852 table_data.tables_3d,
853 vec![
854 Table3D::new(vec![vec![vec![0, 1]]]),
855 Table3D::new(vec![vec![vec![0, 2]]])
856 ]
857 );
858 name_to_table.insert(String::from("t2"), 1);
859 assert_eq!(table_data.name_to_table_3d, name_to_table);
860 }
861
862 #[test]
863 fn add_table_3d_err() {
864 let mut table_data = TableData::default();
865 let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
866 assert!(t.is_ok());
867 let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
868 assert!(t.is_err());
869 assert_eq!(
870 table_data.tables_3d,
871 vec![Table3D::new(vec![vec![vec![0, 1]]])]
872 );
873 let mut name_to_table = FxHashMap::default();
874 name_to_table.insert(String::from("t1"), 0);
875 assert_eq!(table_data.name_to_table_3d, name_to_table);
876 }
877
878 #[test]
879 fn add_table_3d_empty_1d_err() {
880 let mut table_data: TableData<Element> = TableData::default();
881 let t = table_data.add_table_3d(String::from("t1"), vec![]);
882 assert!(t.is_err());
883 assert_eq!(table_data.tables_3d, vec![]);
884 let name_to_table = FxHashMap::default();
885 assert_eq!(table_data.name_to_table_3d, name_to_table);
886 }
887
888 #[test]
889 fn add_table_3d_empty_2d_err() {
890 let mut table_data: TableData<Element> = TableData::default();
891 let t = table_data.add_table_3d(String::from("t1"), vec![vec![]]);
892 assert!(t.is_err());
893 assert_eq!(table_data.tables_3d, vec![]);
894 let name_to_table = FxHashMap::default();
895 assert_eq!(table_data.name_to_table_3d, name_to_table);
896 }
897
898 #[test]
899 fn add_table_3d_empty_3d_err() {
900 let mut table_data: TableData<Element> = TableData::default();
901 let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![]]]);
902 assert!(t.is_err());
903 assert_eq!(table_data.tables_3d, vec![]);
904 let name_to_table = FxHashMap::default();
905 assert_eq!(table_data.name_to_table_3d, name_to_table);
906 }
907
908 // #[test]
909 // fn set_table_3d_ok() {
910 // let mut table_data = TableData::default();
911 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
912 // assert!(t.is_ok());
913 // let t = t.unwrap();
914 // let result = table_data.set_table_3d(t, 0, 0, 0, 1);
915 // assert!(result.is_ok());
916 // assert_eq!(
917 // table_data.tables_3d,
918 // vec![Table3D::new(vec![vec![vec![1, 1]]])]
919 // );
920 // }
921
922 // #[test]
923 // fn set_table_3d_err() {
924 // let mut table_data = TableData::default();
925 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
926 // assert!(t.is_ok());
927
928 // let mut table_data1 = TableData::default();
929 // let t = table_data1.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
930 // assert!(t.is_ok());
931 // let t = table_data1.add_table_3d(String::from("t2"), vec![vec![vec![0, 1]]]);
932 // assert!(t.is_ok());
933 // let t = t.unwrap();
934 // let result = table_data.set_table_3d(t, 0, 0, 0, 1);
935 // assert!(result.is_err());
936 // assert_eq!(
937 // table_data.tables_3d,
938 // vec![Table3D::new(vec![vec![vec![0, 1]]])]
939 // );
940 // }
941
942 // #[test]
943 // fn update_table_3d_ok() {
944 // let mut table_data = TableData::default();
945 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
946 // assert!(t.is_ok());
947 // let t = t.unwrap();
948 // let result = table_data.update_table_3d(t, vec![vec![vec![1, 1]]]);
949 // assert!(result.is_ok());
950 // assert_eq!(
951 // table_data.tables_3d,
952 // vec![Table3D::new(vec![vec![vec![1, 1]]])]
953 // );
954 // }
955
956 // #[test]
957 // fn update_table_3d_err() {
958 // let mut table_data = TableData::default();
959 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
960 // assert!(t.is_ok());
961
962 // let mut table_data1 = TableData::default();
963 // let t = table_data1.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
964 // assert!(t.is_ok());
965 // let t = table_data1.add_table_3d(String::from("t2"), vec![vec![vec![0, 1]]]);
966 // assert!(t.is_ok());
967 // let t = t.unwrap();
968 // let result = table_data.update_table_3d(t, vec![vec![vec![1, 1]]]);
969 // assert!(result.is_err());
970 // assert_eq!(
971 // table_data.tables_3d,
972 // vec![Table3D::new(vec![vec![vec![0, 1]]])]
973 // );
974 // }
975
976 // #[test]
977 // fn update_table_3d_empty_1d_err() {
978 // let mut table_data = TableData::default();
979 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
980 // assert!(t.is_ok());
981 // let t = table_data.add_table_3d(String::from("t2"), vec![]);
982 // assert!(t.is_err());
983 // assert_eq!(
984 // table_data.tables_3d,
985 // vec![Table3D::new(vec![vec![vec![0, 1]]])]
986 // );
987 // }
988
989 // #[test]
990 // fn update_table_3d_empty_2d_err() {
991 // let mut table_data = TableData::default();
992 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
993 // assert!(t.is_ok());
994 // let t = table_data.add_table_3d(String::from("t2"), vec![vec![]]);
995 // assert!(t.is_err());
996 // assert_eq!(
997 // table_data.tables_3d,
998 // vec![Table3D::new(vec![vec![vec![0, 1]]])]
999 // );
1000 // }
1001
1002 // #[test]
1003 // fn update_table_3d_empty_3d_err() {
1004 // let mut table_data = TableData::default();
1005 // let t = table_data.add_table_3d(String::from("t1"), vec![vec![vec![0, 1]]]);
1006 // assert!(t.is_ok());
1007 // let t = table_data.add_table_3d(String::from("t2"), vec![vec![vec![]]]);
1008 // assert!(t.is_err());
1009 // assert_eq!(
1010 // table_data.tables_3d,
1011 // vec![Table3D::new(vec![vec![vec![0, 1]]])]
1012 // );
1013 // }
1014
1015 #[test]
1016 fn add_table_ok() {
1017 let mut table_data = TableData::default();
1018 let mut map = FxHashMap::default();
1019 map.insert(vec![0, 0, 0, 1], 1);
1020 let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1021 assert!(t.is_ok());
1022 let t = t.unwrap();
1023 assert_eq!(t.id(), 0);
1024 assert_eq!(table_data.tables, vec![Table::new(map.clone(), 0)]);
1025 let mut name_to_table = FxHashMap::default();
1026 name_to_table.insert(String::from("t1"), 0);
1027 assert_eq!(table_data.name_to_table, name_to_table);
1028 let mut map2 = FxHashMap::default();
1029 map2.insert(vec![0, 0, 0, 1], 2);
1030 let t = table_data.add_table(String::from("t2"), map2.clone(), 1);
1031 assert!(t.is_ok());
1032 let t = t.unwrap();
1033 assert_eq!(t.id(), 1);
1034 assert_eq!(
1035 table_data.tables,
1036 vec![Table::new(map, 0), Table::new(map2, 1)]
1037 );
1038 name_to_table.insert(String::from("t2"), 1);
1039 assert_eq!(table_data.name_to_table, name_to_table);
1040 }
1041
1042 #[test]
1043 fn add_table_err() {
1044 let mut table_data = TableData::default();
1045 let mut map = FxHashMap::default();
1046 map.insert(vec![0, 0, 0, 1], 1);
1047 let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1048 assert!(t.is_ok());
1049 let t = table_data.add_table(String::from("t1"), map.clone(), 1);
1050 assert!(t.is_err());
1051 assert_eq!(table_data.tables, vec![Table::new(map, 0)]);
1052 let mut name_to_table = FxHashMap::default();
1053 name_to_table.insert(String::from("t1"), 0);
1054 assert_eq!(table_data.name_to_table, name_to_table);
1055 }
1056
1057 // #[test]
1058 // fn set_table_ok() {
1059 // let mut table_data = TableData::default();
1060 // let mut map = FxHashMap::default();
1061 // map.insert(vec![0, 0, 0, 1], 1);
1062 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1063 // assert!(t.is_ok());
1064 // let t = t.unwrap();
1065 // let result = table_data.set_table(t, vec![0, 0, 0, 0], 1);
1066 // assert!(result.is_ok());
1067 // map.insert(vec![0, 0, 0, 0], 1);
1068 // assert_eq!(table_data.tables, vec![Table::new(map, 0)]);
1069 // }
1070
1071 // #[test]
1072 // fn set_table_err() {
1073 // let mut table_data = TableData::default();
1074 // let mut map = FxHashMap::default();
1075 // map.insert(vec![0, 0, 0, 1], 1);
1076 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1077 // assert!(t.is_ok());
1078
1079 // let mut table_data1 = TableData::default();
1080 // let t = table_data1.add_table(String::from("t1"), map.clone(), 1);
1081 // assert!(t.is_ok());
1082 // let t = table_data1.add_table(String::from("t2"), map.clone(), 2);
1083 // assert!(t.is_ok());
1084 // let t = t.unwrap();
1085 // let result = table_data.set_table(t, vec![0, 0, 0, 0], 1);
1086 // assert!(result.is_err());
1087 // assert_eq!(table_data.tables, vec![Table::new(map, 0)]);
1088 // }
1089
1090 // #[test]
1091 // fn set_default_ok() {
1092 // let mut table_data = TableData::default();
1093 // let mut map = FxHashMap::default();
1094 // map.insert(vec![0, 0, 0, 1], 1);
1095 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1096 // assert!(t.is_ok());
1097 // let t = t.unwrap();
1098 // let result = table_data.set_default(t, 1);
1099 // assert!(result.is_ok());
1100 // assert_eq!(table_data.tables, vec![Table::new(map, 1)]);
1101 // }
1102
1103 // #[test]
1104 // fn set_default_err() {
1105 // let mut table_data = TableData::default();
1106 // let mut map = FxHashMap::default();
1107 // map.insert(vec![0, 0, 0, 1], 1);
1108 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1109 // assert!(t.is_ok());
1110
1111 // let mut table_data1 = TableData::default();
1112 // let t = table_data1.add_table(String::from("t1"), map.clone(), 0);
1113 // assert!(t.is_ok());
1114 // let t = table_data1.add_table(String::from("t2"), map.clone(), 0);
1115 // assert!(t.is_ok());
1116 // let t = t.unwrap();
1117 // let result = table_data.set_default(t, 1);
1118 // assert!(result.is_err());
1119 // assert_eq!(table_data.tables, vec![Table::new(map, 0)]);
1120 // }
1121
1122 // #[test]
1123 // fn update_table_ok() {
1124 // let mut table_data = TableData::default();
1125 // let mut map = FxHashMap::default();
1126 // map.insert(vec![0, 0, 0, 1], 1);
1127 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1128 // assert!(t.is_ok());
1129 // let t = t.unwrap();
1130 // let mut map = FxHashMap::default();
1131 // map.insert(vec![0, 0, 0, 1], 2);
1132 // let result = table_data.update_table(t, map.clone(), 1);
1133 // assert!(result.is_ok());
1134 // assert_eq!(table_data.tables, vec![Table::new(map, 1)]);
1135 // }
1136
1137 // #[test]
1138 // fn update_table_err() {
1139 // let mut table_data = TableData::default();
1140 // let mut map = FxHashMap::default();
1141 // map.insert(vec![0, 0, 0, 1], 1);
1142 // let t = table_data.add_table(String::from("t1"), map.clone(), 0);
1143 // assert!(t.is_ok());
1144
1145 // let mut table_data1 = TableData::default();
1146 // let t = table_data1.add_table(String::from("t1"), map.clone(), 1);
1147 // assert!(t.is_ok());
1148 // let t = table_data1.add_table(String::from("t2"), map.clone(), 2);
1149 // assert!(t.is_ok());
1150 // let t = t.unwrap();
1151 // let mut map2 = FxHashMap::default();
1152 // map2.insert(vec![0, 0, 0, 1], 2);
1153 // let result = table_data.update_table(t, map2, 3);
1154 // assert!(result.is_err());
1155 // assert_eq!(table_data.tables, vec![Table::new(map, 0)]);
1156 // }
1157
1158 #[test]
1159 fn get_name_set() {
1160 let mut name_to_constant = FxHashMap::default();
1161 name_to_constant.insert(String::from("i0"), 0);
1162
1163 let tables_1d = vec![table::Table1D::new(vec![10, 20, 30])];
1164 let mut name_to_table_1d = FxHashMap::default();
1165 name_to_table_1d.insert(String::from("i1"), 0);
1166
1167 let tables_2d = vec![table::Table2D::new(vec![
1168 vec![10, 20, 30],
1169 vec![10, 10, 10],
1170 vec![10, 10, 10],
1171 ])];
1172 let mut name_to_table_2d = FxHashMap::default();
1173 name_to_table_2d.insert(String::from("i2"), 0);
1174
1175 let tables_3d = vec![table::Table3D::new(vec![
1176 vec![vec![10, 20, 30], vec![0, 0, 0], vec![0, 0, 0]],
1177 vec![vec![0, 0, 0], vec![0, 0, 0], vec![0, 0, 0]],
1178 vec![vec![0, 0, 0], vec![0, 0, 0], vec![0, 0, 0]],
1179 ])];
1180 let mut name_to_table_3d = FxHashMap::default();
1181 name_to_table_3d.insert(String::from("i3"), 0);
1182
1183 let mut map = FxHashMap::default();
1184 let key = vec![0, 1, 0, 0];
1185 map.insert(key, 100);
1186 let key = vec![0, 1, 0, 1];
1187 map.insert(key, 200);
1188 let key = vec![0, 1, 2, 0];
1189 map.insert(key, 300);
1190 let key = vec![0, 1, 2, 1];
1191 map.insert(key, 400);
1192 let tables = vec![table::Table::new(map, 0)];
1193 let mut name_to_table = FxHashMap::default();
1194 name_to_table.insert(String::from("i4"), 0);
1195
1196 let integer_tables = TableData {
1197 name_to_constant,
1198 tables_1d,
1199 name_to_table_1d,
1200 tables_2d,
1201 name_to_table_2d,
1202 tables_3d,
1203 name_to_table_3d,
1204 tables,
1205 name_to_table,
1206 };
1207 let mut expected = FxHashSet::default();
1208 expected.insert(String::from("i0"));
1209 expected.insert(String::from("i1"));
1210 expected.insert(String::from("i2"));
1211 expected.insert(String::from("i3"));
1212 expected.insert(String::from("i4"));
1213 assert_eq!(integer_tables.get_name_set(), expected);
1214 }
1215
1216 #[test]
1217 fn check_table_1d() {
1218 let mut table_data = TableData::default();
1219 let result = table_data.check_table_1d(0);
1220 assert!(result.is_err());
1221 let t = table_data.add_table_1d(String::from("t"), vec![0, 1]);
1222 assert!(t.is_ok());
1223 let result = table_data.check_table_1d(0);
1224 assert!(result.is_ok());
1225 let result = table_data.check_table_1d(1);
1226 assert!(result.is_err());
1227 }
1228
1229 #[test]
1230 fn check_table_2d() {
1231 let mut table_data = TableData::default();
1232 let result = table_data.check_table_2d(0);
1233 assert!(result.is_err());
1234 let t = table_data.add_table_2d(String::from("t"), vec![vec![0, 1]]);
1235 assert!(t.is_ok());
1236 let result = table_data.check_table_2d(0);
1237 assert!(result.is_ok());
1238 let result = table_data.check_table_2d(1);
1239 assert!(result.is_err());
1240 }
1241
1242 #[test]
1243 fn check_table_3d() {
1244 let mut table_data = TableData::default();
1245 let result = table_data.check_table_3d(0);
1246 assert!(result.is_err());
1247 let t = table_data.add_table_3d(String::from("t"), vec![vec![vec![0, 1]]]);
1248 assert!(t.is_ok());
1249 let result = table_data.check_table_3d(0);
1250 assert!(result.is_ok());
1251 let result = table_data.check_table_3d(1);
1252 assert!(result.is_err());
1253 }
1254
1255 #[test]
1256 fn check_table() {
1257 let mut table_data = TableData::default();
1258 let result = table_data.check_table(0);
1259 assert!(result.is_err());
1260 let t = table_data.add_table(String::from("t"), FxHashMap::default(), 0);
1261 assert!(t.is_ok());
1262 let result = table_data.check_table(0);
1263 assert!(result.is_ok());
1264 let result = table_data.check_table(1);
1265 assert!(result.is_err());
1266 }
1267
1268 #[test]
1269 fn relative_eq() {
1270 let mut name_to_table_1d = FxHashMap::default();
1271 name_to_table_1d.insert(String::from("t0"), 0);
1272 name_to_table_1d.insert(String::from("t1"), 1);
1273 let t1 = TableData {
1274 tables_1d: vec![
1275 table::Table1D::new(vec![1.0, 2.0]),
1276 table::Table1D::new(vec![2.0, 3.0]),
1277 ],
1278 name_to_table_1d: name_to_table_1d.clone(),
1279 ..Default::default()
1280 };
1281 let t2 = TableData {
1282 tables_1d: vec![
1283 table::Table1D::new(vec![1.0, 2.0]),
1284 table::Table1D::new(vec![2.0, 3.0]),
1285 ],
1286 name_to_table_1d: name_to_table_1d.clone(),
1287 ..Default::default()
1288 };
1289 assert_relative_eq!(t1, t2);
1290 let t2 = TableData {
1291 tables_1d: vec![
1292 table::Table1D::new(vec![1.0, 2.0]),
1293 table::Table1D::new(vec![3.0, 3.0]),
1294 ],
1295 name_to_table_1d,
1296 ..Default::default()
1297 };
1298 assert_relative_ne!(t1, t2);
1299 let mut name_to_table_1d = FxHashMap::default();
1300 name_to_table_1d.insert(String::from("t0"), 0);
1301 let t2 = TableData {
1302 tables_1d: vec![table::Table1D::new(vec![1.0, 2.0])],
1303 name_to_table_1d,
1304 ..Default::default()
1305 };
1306 assert_relative_ne!(t1, t2);
1307 }
1308}