1use std::{collections::hash_map::Iter, rc::Rc};
2
3use super::*;
4use crate::{
5 JwstCodecResult,
6 doc::{AsInner, Node, Parent, YTypeRef},
7 impl_type,
8};
9
10impl_type!(Map);
11
12pub(crate) trait MapType: AsInner<Inner = YTypeRef> {
13 fn _id(&self) -> Option<Id> {
14 self.as_inner().ty().and_then(|ty| ty.item.get().map(|item| item.id))
15 }
16
17 fn _insert<V: Into<Value>>(&mut self, key: String, value: V) -> JwstCodecResult {
18 if let Some((mut store, mut ty)) = self.as_inner().write() {
19 let left = ty.map.get(&SmolStr::new(&key)).cloned();
20
21 let item = store.create_item(
22 value.into().into(),
23 left.unwrap_or(Somr::none()),
24 Somr::none(),
25 Some(Parent::Type(self.as_inner().clone())),
26 Some(SmolStr::new(key)),
27 );
28 store.integrate(Node::Item(item), 0, Some(&mut ty))?;
29 }
30
31 Ok(())
32 }
33
34 fn _get(&self, key: &str) -> Option<Value> {
35 self.as_inner().ty().and_then(|ty| {
36 ty.map.get(key).and_then(|item| {
37 if let Some(item) = item.get() {
38 if item.deleted() {
39 return None;
40 }
41
42 Some(Value::from(&item.content))
43 } else {
44 None
45 }
46 })
47 })
48 }
49
50 fn _contains_key(&self, key: &str) -> bool {
51 if let Some(ty) = self.as_inner().ty() {
52 ty.map
53 .get(key)
54 .and_then(|item| item.get())
55 .is_some_and(|item| !item.deleted())
56 } else {
57 false
58 }
59 }
60
61 fn _remove(&mut self, key: &str) {
62 if let Some((mut store, mut ty)) = self.as_inner().write()
63 && let Some(item) = ty.map.get(key).cloned()
64 && let Some(item) = item.get()
65 {
66 store.delete_item(item, Some(&mut ty));
67 }
68 }
69
70 fn _len(&self) -> u64 {
71 self._keys().count() as u64
72 }
73
74 fn _iter(&self) -> EntriesInnerIterator<'_> {
75 let ty = self.as_inner().ty();
76
77 if let Some(ty) = ty {
78 let ty = Rc::new(ty);
79
80 EntriesInnerIterator {
81 iter: Some(unsafe { &*Rc::as_ptr(&ty) }.map.iter()),
82 _lock: Some(ty),
83 }
84 } else {
85 EntriesInnerIterator {
86 _lock: None,
87 iter: None,
88 }
89 }
90 }
91
92 fn _keys(&self) -> KeysIterator<'_> {
93 KeysIterator(self._iter())
94 }
95
96 fn _values(&self) -> ValuesIterator<'_> {
97 ValuesIterator(self._iter())
98 }
99
100 fn _entries(&self) -> EntriesIterator<'_> {
101 EntriesIterator(self._iter())
102 }
103}
104
105pub(crate) struct EntriesInnerIterator<'a> {
106 _lock: Option<Rc<RwLockReadGuard<'a, YType>>>,
107 iter: Option<Iter<'a, SmolStr, ItemRef>>,
108}
109
110pub struct KeysIterator<'a>(EntriesInnerIterator<'a>);
111pub struct ValuesIterator<'a>(EntriesInnerIterator<'a>);
112pub struct EntriesIterator<'a>(EntriesInnerIterator<'a>);
113
114impl<'a> Iterator for EntriesInnerIterator<'a> {
115 type Item = (&'a str, &'a Item);
116
117 fn next(&mut self) -> Option<Self::Item> {
118 if let Some(iter) = &mut self.iter {
119 for (k, v) in iter {
120 if let Some(item) = v.get()
121 && !item.deleted()
122 {
123 return Some((k.as_str(), item));
124 }
125 }
126
127 None
128 } else {
129 None
130 }
131 }
132}
133
134impl<'a> Iterator for KeysIterator<'a> {
135 type Item = &'a str;
136
137 fn next(&mut self) -> Option<Self::Item> {
138 self.0.next().map(|(k, _)| k)
139 }
140}
141
142impl Iterator for ValuesIterator<'_> {
143 type Item = Value;
144
145 fn next(&mut self) -> Option<Self::Item> {
146 self.0.next().map(|(_, v)| Value::from(&v.content))
147 }
148}
149
150impl<'a> Iterator for EntriesIterator<'a> {
151 type Item = (&'a str, Value);
152
153 fn next(&mut self) -> Option<Self::Item> {
154 self.0.next().map(|(k, v)| (k, Value::from(&v.content)))
155 }
156}
157
158impl MapType for Map {}
159
160impl Map {
161 #[inline(always)]
162 pub fn id(&self) -> Option<Id> {
163 self._id()
164 }
165
166 #[inline(always)]
167 pub fn insert<V: Into<Value>>(&mut self, key: String, value: V) -> JwstCodecResult {
168 self._insert(key, value)
169 }
170
171 #[inline(always)]
172 pub fn get(&self, key: &str) -> Option<Value> {
173 self._get(key)
174 }
175
176 #[inline(always)]
177 pub fn contains_key(&self, key: &str) -> bool {
178 self._contains_key(key)
179 }
180
181 #[inline(always)]
182 pub fn remove(&mut self, key: &str) {
183 self._remove(key)
184 }
185
186 #[inline(always)]
187 pub fn len(&self) -> u64 {
188 self._len()
189 }
190
191 #[inline(always)]
192 pub fn is_empty(&self) -> bool {
193 self.len() == 0
194 }
195
196 #[inline(always)]
197 pub fn iter(&self) -> EntriesIterator<'_> {
198 self._entries()
199 }
200
201 #[inline(always)]
202 pub fn entries(&self) -> EntriesIterator<'_> {
203 self._entries()
204 }
205
206 #[inline(always)]
207 pub fn keys(&self) -> KeysIterator<'_> {
208 self._keys()
209 }
210
211 #[inline(always)]
212 pub fn values(&self) -> ValuesIterator<'_> {
213 self._values()
214 }
215}
216
217impl serde::Serialize for Map {
218 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
219 use serde::ser::SerializeMap;
220
221 let mut map = serializer.serialize_map(Some(self.len() as usize))?;
222 for (key, value) in self.iter() {
223 map.serialize_entry(&key, &value)?;
224 }
225 map.end()
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::*;
232 use crate::{Any, Doc, loom_model};
233
234 #[test]
235 fn test_map_basic() {
236 loom_model!({
237 let doc = Doc::new();
238 let mut map = doc.get_or_create_map("map").unwrap();
239 map.insert("1".to_string(), "value").unwrap();
240 assert_eq!(map.get("1").unwrap(), Value::Any(Any::String("value".to_string())));
241 assert!(!map.contains_key("nonexistent_key"));
242 assert_eq!(map.len(), 1);
243 assert!(map.contains_key("1"));
244 map.remove("1");
245 assert!(!map.contains_key("1"));
246 assert_eq!(map.len(), 0);
247 });
248 }
249
250 #[test]
251 fn test_map_equal() {
252 loom_model!({
253 let doc = Doc::new();
254 let mut map = doc.get_or_create_map("map").unwrap();
255 map.insert("1".to_string(), "value").unwrap();
256 map.insert("2".to_string(), false).unwrap();
257
258 let binary = doc.encode_update_v1().unwrap();
259 let new_doc = Doc::try_from_binary_v1(binary).unwrap();
260 let map = new_doc.get_or_create_map("map").unwrap();
261 assert_eq!(map.get("1").unwrap(), Value::Any(Any::String("value".to_string())));
262 assert_eq!(map.get("2").unwrap(), Value::Any(Any::False));
263 assert_eq!(map.len(), 2);
264 });
265 }
266
267 #[test]
268 fn test_map_renew_value() {
269 loom_model!({
270 let doc = Doc::new();
271 let mut map = doc.get_or_create_map("map").unwrap();
272 map.insert("1".to_string(), "value").unwrap();
273 map.insert("1".to_string(), "value2").unwrap();
274 assert_eq!(map.get("1").unwrap(), Value::Any(Any::String("value2".to_string())));
275 assert_eq!(map.len(), 1);
276 });
277 }
278
279 #[test]
280 fn test_map_re_encode() {
281 loom_model!({
282 let binary = {
283 let doc = Doc::new();
284 let mut map = doc.get_or_create_map("map").unwrap();
285 map.insert("1".to_string(), "value1").unwrap();
286 map.insert("2".to_string(), "value2").unwrap();
287 doc.encode_update_v1().unwrap()
288 };
289
290 {
291 let doc = Doc::try_from_binary_v1(binary).unwrap();
292 let map = doc.get_or_create_map("map").unwrap();
293 assert_eq!(map.get("1").unwrap(), Value::Any(Any::String("value1".to_string())));
294 assert_eq!(map.get("2").unwrap(), Value::Any(Any::String("value2".to_string())));
295 }
296 });
297 }
298
299 #[test]
300 fn test_map_iter() {
301 loom_model!({
302 let doc = Doc::new();
303 let mut map = doc.get_or_create_map("map").unwrap();
304 map.insert("1".to_string(), "value1").unwrap();
305 map.insert("2".to_string(), "value2").unwrap();
306 let mut vec = map.entries().collect::<Vec<_>>();
307
308 vec.sort_by(|a, b| a.0.cmp(b.0));
310
311 assert_eq!(
312 vec,
313 vec![
314 ("1", Value::Any(Any::String("value1".to_string()))),
315 ("2", Value::Any(Any::String("value2".to_string())))
316 ]
317 )
318 });
319 }
320}