1use std::{
2 collections::HashMap,
3 fmt,
4 ops::{Index, IndexMut},
5 sync::Arc,
6};
7
8use linked_hash_map::{Iter, LinkedHashMap};
9use serde::{Deserialize, Serialize};
10
11use crate::parse::{Encode, Token};
12
13type Patch = Arc<dyn Fn(&mut PatchedMap, &mut Token) + Send + Sync>;
14#[derive(Clone, Default, Serialize, Deserialize)]
15pub struct PatchedMap {
16 #[serde(flatten)]
17 raw_hashmap: LinkedHashMap<String, Token>,
18 #[serde(skip)]
19 pub patches: HashMap<String, Patch>,
20}
21
22impl PatchedMap {
23 pub fn new() -> Self {
24 PatchedMap {
25 raw_hashmap: LinkedHashMap::new(),
26 patches: HashMap::new(),
27 }
28 }
29
30 pub fn with_capacity(capacity: usize) -> Self {
31 PatchedMap {
32 raw_hashmap: LinkedHashMap::with_capacity(capacity),
33 patches: HashMap::new(),
34 }
35 }
36
37 pub fn push_back<T: Into<Token>>(&mut self, key_str: &str, value: T) -> bool {
38 let key = key_str.to_string();
39
40 if self.raw_hashmap.contains_key(&key) {
41 return false;
42 }
43
44 self.raw_hashmap.insert(key, value.into());
45 true
46 }
47
48 pub fn update<T: Into<Token>>(&mut self, key: &str, value: T) -> Result<(), String> {
49 if !self.raw_hashmap.contains_key(key) {
50 return Err("Key doesn't exist!".to_string());
51 }
52
53 self.raw_hashmap[key] = value.into();
54 Ok(())
55 }
56
57 pub fn contains(&self, key: &str) -> bool {
58 self.raw_hashmap.contains_key(&key.to_string())
59 }
60
61 pub fn keys(&self) -> linked_hash_map::Keys<String, Token> {
62 self.raw_hashmap.keys()
63 }
64
65 pub fn iter(&self) -> SeqIter {
66 SeqIter {
67 index: 0,
68 ele: self.raw_hashmap.iter(),
69 }
70 }
71}
72
73impl Index<&str> for PatchedMap {
74 type Output = Token;
75 fn index(&self, index: &str) -> &Self::Output {
76 &self.raw_hashmap[&index.to_string()]
77 }
78}
79
80impl IndexMut<&str> for PatchedMap {
81 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
82 self.raw_hashmap.get_mut(&index.to_string()).unwrap()
83 }
84}
85
86pub struct SeqIter<'a> {
87 index: usize,
88 ele: Iter<'a, String, Token>,
89}
90
91impl<'a> Iterator for SeqIter<'a> {
92 type Item = (&'a String, &'a Token);
93
94 fn next(&mut self) -> Option<Self::Item> {
95 match self.ele.next() {
96 Some((key, value)) => {
97 self.index += 1;
98 Some((key, value))
99 }
100 None => None,
101 }
102 }
103}
104
105impl Encode for PatchedMap {
106 fn to_le_vec(&self) -> Vec<u8> {
107 self.iter()
108 .flat_map(|(_, token)| token.to_le_vec())
109 .collect()
110 }
111}
112
113impl fmt::Debug for PatchedMap {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 f.write_str("PatchedMap")?;
116 f.debug_map()
117 .entries(self.iter().map(|(key, value)| (key, value)))
118 .finish()
119 }
120}