papergrid/config/
entity_map.rs
1use fnv::FnvHashMap;
2
3use super::{Entity, Position};
4
5#[derive(Debug, Clone, Default)]
6pub(crate) struct EntityMap<T> {
7 pub(crate) global: T,
10 pub(crate) columns: FnvHashMap<usize, T>,
11 pub(crate) rows: FnvHashMap<usize, T>,
12 pub(crate) cells: FnvHashMap<Position, T>,
13}
14
15impl<T> EntityMap<T> {
16 pub(crate) fn new(global: T) -> Self {
17 Self {
18 global,
19 rows: FnvHashMap::default(),
20 columns: FnvHashMap::default(),
21 cells: FnvHashMap::default(),
22 }
23 }
24
25 pub(crate) fn lookup(&self, entity: Entity) -> &T {
26 if self.rows.is_empty() && self.columns.is_empty() && self.cells.is_empty() {
27 return &self.global;
28 }
29
30 match entity {
31 Entity::Column(col) => self.columns.get(&col).unwrap_or(&self.global),
32 Entity::Row(row) => self.rows.get(&row).unwrap_or(&self.global),
33 Entity::Cell(row, col) => self
34 .cells
35 .get(&(row, col))
36 .or_else(|| self.columns.get(&col))
37 .or_else(|| self.rows.get(&row))
38 .unwrap_or(&self.global),
39 Entity::Global => &self.global,
40 }
41 }
42
43 pub(crate) fn invalidate(&mut self, entity: Entity) {
44 match entity {
45 Entity::Global => {
46 self.cells.clear();
47 self.rows.clear();
48 self.columns.clear();
49 }
50 Entity::Column(col) => self.cells.retain(|&(_, c), _| c != col),
51 Entity::Row(row) => self.cells.retain(|&(r, _), _| r != row),
52 Entity::Cell(_, _) => (),
53 }
54 }
55}
56
57impl<T: Clone> EntityMap<T> {
58 pub(crate) fn set(&mut self, entity: Entity, value: T) {
59 self.invalidate(entity);
60
61 match entity {
62 Entity::Column(col) => {
63 for &row in self.rows.keys() {
64 self.cells.insert((row, col), value.clone());
65 }
66
67 self.columns.insert(col, value);
68 }
69 Entity::Row(row) => {
70 for &col in self.columns.keys() {
71 self.cells.insert((row, col), value.clone());
72 }
73
74 self.rows.insert(row, value);
75 }
76 Entity::Cell(row, col) => {
77 self.cells.insert((row, col), value);
78 }
79 Entity::Global => self.global = value,
80 }
81 }
82}