swamp_script_core_extra/
map2.rs1use seq_map::SeqMap;
2use std::fmt::Debug;
3use std::fmt::Display;
4use std::hash::Hash;
5
6pub fn print_grid<R, C, V>(map: &Map2<R, C, V>)
7where
8 R: Display + Eq + Hash + Clone,
9 C: Display + Eq + Hash + Clone,
10 V: Debug + Clone,
11{
12 let rows: Vec<_> = map.rows.keys().collect();
13 let cols: Vec<_> = map.columns.keys().collect();
14
15 print!("{:>10} ", ""); for col in &cols {
18 print!("{:>10} ", col);
19 }
20 println!();
21
22 for row in rows {
23 print!("{:>10} ", row);
24 for col in &cols {
25 if let Some(value) = map.get(col, row) {
26 print!("{:?} ", value);
27 } else {
28 print!("{:>10} ", "");
29 }
30 }
31 println!();
32 }
33}
34
35#[derive(Debug, Clone)]
36pub struct Map2<R: Eq + Hash, C: Eq + Hash, V> {
37 rows: SeqMap<R, SeqMap<C, V>>,
38 columns: SeqMap<C, SeqMap<R, V>>,
39}
40
41impl<R, C, V> Map2<R, C, V>
42where
43 R: Eq + Hash + Clone,
44 C: Eq + Hash + Clone,
45 V: Clone,
46{
47 #[must_use]
48 pub fn new() -> Self {
49 Self {
50 rows: SeqMap::new(),
51 columns: SeqMap::new(),
52 }
53 }
54
55 pub fn rows(&self) -> &SeqMap<R, SeqMap<C, V>> {
56 &self.rows
57 }
58
59 pub fn columns(&self) -> &SeqMap<C, SeqMap<R, V>> {
60 &self.columns
61 }
62
63 pub fn get(&self, col: &C, row: &R) -> Option<&V> {
65 self.rows.get(row).and_then(|row_map| row_map.get(col))
66 }
67
68 pub fn get_row(&self, row: &R) -> Option<&SeqMap<C, V>> {
70 self.rows.get(row)
71 }
72
73 pub fn get_column(&self, col: &C) -> Option<&SeqMap<R, V>> {
75 self.columns.get(col)
76 }
77
78 pub fn has(&self, col: &C, row: &R) -> bool {
79 self.rows
80 .get(row)
81 .map_or(false, |row_map| row_map.contains_key(col))
82 }
83
84 pub fn insert(&mut self, col: C, row: R, value: V) {
87 if self.rows.contains_key(&row) {
89 self.rows
90 .get_mut(&row)
91 .unwrap()
92 .insert(col.clone(), value.clone())
93 .unwrap();
94 } else {
95 let mut row_map = SeqMap::new();
96 row_map.insert(col.clone(), value.clone()).unwrap();
97 self.rows.insert(row.clone(), row_map).unwrap();
98 };
99
100 if self.columns.contains_key(&col) {
102 self.columns
103 .get_mut(&col)
104 .unwrap()
105 .insert(row, value)
106 .unwrap();
107 } else {
108 let mut col_map = SeqMap::new();
109 col_map.insert(row, value).unwrap();
110 self.columns.insert(col, col_map).unwrap();
111 }
112 }
113
114 pub fn remove(&mut self, col: &C, row: &R) -> Option<V> {
117 let removed = if let Some(row_map) = self.rows.get_mut(row) {
119 let removed = row_map.remove(col);
120 if row_map.is_empty() {
122 self.rows.remove(row);
123 }
124 removed
125 } else {
126 None
127 };
128
129 if let Some(col_map) = self.columns.get_mut(col) {
131 col_map.remove(row);
132 if col_map.is_empty() {
134 self.columns.remove(col);
135 }
136 }
137 removed
138 }
139}