manabrew_engine/card/
card_changed_words.rs1use std::collections::{BTreeMap, HashMap};
4
5#[derive(Debug, Clone)]
6struct WordHolder {
7 old_word: String,
8 new_word: String,
9 clear: bool,
10}
11
12impl WordHolder {
13 fn clear_entry() -> Self {
14 Self {
15 old_word: String::new(),
16 new_word: String::new(),
17 clear: true,
18 }
19 }
20
21 fn replacement(old_word: &str, new_word: &str) -> Self {
22 Self {
23 old_word: old_word.to_string(),
24 new_word: new_word.to_string(),
25 clear: false,
26 }
27 }
28}
29
30#[derive(Debug, Clone, Default)]
31pub struct CardChangedWords {
32 map: BTreeMap<(u64, u64), WordHolder>,
33 is_dirty: bool,
34 result_cache: HashMap<String, String>,
35}
36
37impl CardChangedWords {
38 pub fn add_empty(&mut self, timestamp: u64, static_id: u64) -> u64 {
39 self.map
40 .insert((timestamp, static_id), WordHolder::clear_entry());
41 self.is_dirty = true;
42 timestamp
43 }
44
45 pub fn add(
46 &mut self,
47 timestamp: u64,
48 static_id: u64,
49 original_word: &str,
50 new_word: &str,
51 ) -> u64 {
52 self.map.insert(
53 (timestamp, static_id),
54 WordHolder::replacement(original_word, new_word),
55 );
56 self.is_dirty = true;
57 timestamp
58 }
59
60 pub fn remove(&mut self, timestamp: u64, static_id: u64) -> bool {
61 let removed = self.map.remove(&(timestamp, static_id)).is_some();
62 if removed {
63 self.is_dirty = true;
64 }
65 removed
66 }
67
68 pub fn clear(&mut self) {
69 self.map.clear();
70 self.result_cache.clear();
71 self.is_dirty = true;
72 }
73
74 pub fn resolved_map(&mut self) -> &HashMap<String, String> {
75 if self.is_dirty {
76 self.result_cache.clear();
77 for holder in self.map.values() {
78 if holder.clear {
79 self.result_cache.clear();
80 continue;
81 }
82
83 let replacements: Vec<(String, String)> = self
84 .result_cache
85 .iter()
86 .filter(|(_, v)| v.as_str() == holder.old_word)
87 .map(|(k, _)| (k.clone(), holder.new_word.clone()))
88 .collect();
89 for (k, v) in replacements {
90 self.result_cache.insert(k, v);
91 }
92
93 self.result_cache
94 .insert(holder.old_word.clone(), holder.new_word.clone());
95 }
96 self.is_dirty = false;
97 }
98 &self.result_cache
99 }
100}