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