1use std::hash::Hash;
8
9use indexmap::{IndexMap, IndexSet};
10use js::conversions::ToJSValConvertible;
11
12use crate::cell::DomRefCell;
13use crate::iterable::Iterable;
14
15pub trait Setlike {
21 type Key: ToJSValConvertible + Clone; fn get_index(&self, index: u32) -> Option<Self::Key>;
25
26 fn size(&self) -> u32;
27 fn add(&self, key: Self::Key);
28 fn has(&self, key: Self::Key) -> bool;
29 fn clear(&self);
30 fn delete(&self, key: Self::Key) -> bool;
31}
32
33impl<T: Setlike> Maplike for T {
37 type Key = <T as Setlike>::Key;
38
39 type Value = <T as Setlike>::Key;
40
41 #[inline]
42 fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)> {
43 self.get_index(index).map(|k| (k.clone(), k))
44 }
45
46 fn get(&self, _key: Self::Key) -> Option<Self::Value> {
47 unimplemented!()
48 }
49
50 #[inline]
51 fn size(&self) -> u32 {
52 self.size()
53 }
54
55 fn set(&self, _key: Self::Key, _value: Self::Value) {
56 unimplemented!()
57 }
58
59 fn has(&self, _key: Self::Key) -> bool {
60 unimplemented!()
61 }
62
63 fn clear(&self) {
64 unimplemented!()
65 }
66
67 fn delete(&self, _key: Self::Key) -> bool {
68 unimplemented!()
69 }
70}
71
72pub trait Maplike {
79 type Key: ToJSValConvertible;
81 type Value: ToJSValConvertible;
83
84 fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)>;
85
86 fn get(&self, key: Self::Key) -> Option<Self::Value>;
87 fn size(&self) -> u32;
88 fn set(&self, key: Self::Key, value: Self::Value);
89 fn has(&self, key: Self::Key) -> bool;
90 fn clear(&self);
91 fn delete(&self, key: Self::Key) -> bool;
92}
93
94impl<T: Maplike> Iterable for T {
95 type Key = T::Key;
96
97 type Value = T::Value;
98
99 #[inline]
100 fn get_iterable_length(&self) -> u32 {
101 self.size()
102 }
103
104 #[inline]
105 fn get_value_at_index(&self, index: u32) -> <T as Maplike>::Value {
106 self.get_index(index).unwrap().1
108 }
109
110 #[inline]
111 fn get_key_at_index(&self, index: u32) -> <T as Maplike>::Key {
112 self.get_index(index).unwrap().0
114 }
115}
116
117impl<K, V> Maplike for DomRefCell<IndexMap<K, V>>
118where
119 K: ToJSValConvertible + Eq + PartialEq + Hash + Clone,
120 V: ToJSValConvertible + Clone,
121{
122 type Key = K;
123 type Value = V;
124
125 #[inline(always)]
126 fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)> {
127 self.borrow()
128 .get_index(index as usize)
129 .map(|(k, v)| (k.to_owned(), v.to_owned()))
130 }
131
132 #[inline(always)]
133 fn get(&self, key: Self::Key) -> Option<Self::Value> {
134 self.borrow().get(&key).cloned()
135 }
136
137 #[inline(always)]
138 fn size(&self) -> u32 {
139 self.borrow().len() as u32
140 }
141
142 #[inline(always)]
143 fn set(&self, key: Self::Key, value: Self::Value) {
144 self.borrow_mut().insert(key, value);
145 }
146
147 #[inline(always)]
148 fn has(&self, key: Self::Key) -> bool {
149 self.borrow().contains_key(&key)
150 }
151
152 #[inline(always)]
153 fn clear(&self) {
154 self.borrow_mut().clear()
155 }
156
157 #[inline(always)]
158 fn delete(&self, key: Self::Key) -> bool {
159 self.borrow_mut().shift_remove(&key).is_some()
160 }
161}
162
163impl<K> Setlike for DomRefCell<IndexSet<K>>
164where
165 K: ToJSValConvertible + Eq + PartialEq + Hash + Clone,
166{
167 type Key = K;
168
169 #[inline(always)]
170 fn get_index(&self, index: u32) -> Option<Self::Key> {
171 self.borrow().get_index(index as usize).cloned()
172 }
173
174 #[inline(always)]
175 fn size(&self) -> u32 {
176 self.borrow().len() as u32
177 }
178
179 #[inline(always)]
180 fn add(&self, key: Self::Key) {
181 self.borrow_mut().insert(key);
182 }
183
184 #[inline(always)]
185 fn has(&self, key: Self::Key) -> bool {
186 self.borrow().contains(&key)
187 }
188
189 #[inline(always)]
190 fn clear(&self) {
191 self.borrow_mut().clear()
192 }
193
194 #[inline(always)]
195 fn delete(&self, key: Self::Key) -> bool {
196 self.borrow_mut().shift_remove(&key)
197 }
198}