script/dom/bindings/
like.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Implementation of `setlike<...>` and `maplike<..., ...>` WebIDL declarations.
6
7use std::cmp::Eq;
8use std::hash::Hash;
9
10use indexmap::{IndexMap, IndexSet};
11use js::conversions::ToJSValConvertible;
12pub(crate) use script_bindings::like::*;
13
14use crate::dom::bindings::cell::DomRefCell;
15
16impl<K> Setlike for DomRefCell<IndexSet<K>>
17where
18    K: ToJSValConvertible + Eq + PartialEq + Hash + Clone,
19{
20    type Key = K;
21
22    #[inline(always)]
23    fn get_index(&self, index: u32) -> Option<Self::Key> {
24        self.borrow().get_index(index as usize).cloned()
25    }
26
27    #[inline(always)]
28    fn size(&self) -> u32 {
29        self.borrow().len() as u32
30    }
31
32    #[inline(always)]
33    fn add(&self, key: Self::Key) {
34        self.borrow_mut().insert(key);
35    }
36
37    #[inline(always)]
38    fn has(&self, key: Self::Key) -> bool {
39        self.borrow().contains(&key)
40    }
41
42    #[inline(always)]
43    fn clear(&self) {
44        self.borrow_mut().clear()
45    }
46
47    #[inline(always)]
48    fn delete(&self, key: Self::Key) -> bool {
49        self.borrow_mut().shift_remove(&key)
50    }
51}
52
53/// Usage:
54/// ```rust
55/// pub(crate) struct TestBindingSetlike {
56///     // setlike<DOMString>
57///     internal: DomRefCell<IndexSet<DOMString>>,
58/// }
59/// impl Setlike for TestBindingSetlike {
60///     type Key = DOMString;
61///     setlike!(self, internal);
62/// }
63/// ```
64#[macro_export]
65macro_rules! setlike {
66    ( $self:ident, $x:ident ) => {
67        #[inline(always)]
68        fn get_index(&$self, index: u32) -> Option<Self::Key> {
69            $self.$x.get_index(index)
70        }
71
72        #[inline(always)]
73        fn size(&$self) -> u32 {
74            $self.$x.size()
75        }
76
77        #[inline(always)]
78        fn add(&$self, key: Self::Key) {
79            $self.$x.add(key)
80        }
81
82        #[inline(always)]
83        fn has(&$self, key: Self::Key) -> bool {
84            $self.$x.has(key)
85        }
86
87        #[inline(always)]
88        fn clear(&$self) {
89            $self.$x.clear()
90        }
91
92        #[inline(always)]
93        fn delete(&$self, key: Self::Key) -> bool {
94            $self.$x.delete(key)
95        }
96    };
97}
98
99impl<K, V> Maplike for DomRefCell<IndexMap<K, V>>
100where
101    K: ToJSValConvertible + Eq + PartialEq + Hash + Clone,
102    V: ToJSValConvertible + Clone,
103{
104    type Key = K;
105    type Value = V;
106
107    #[inline(always)]
108    fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)> {
109        self.borrow()
110            .get_index(index as usize)
111            .map(|(k, v)| (k.to_owned(), v.to_owned()))
112    }
113
114    #[inline(always)]
115    fn get(&self, key: Self::Key) -> Option<Self::Value> {
116        self.borrow().get(&key).cloned()
117    }
118
119    #[inline(always)]
120    fn size(&self) -> u32 {
121        self.borrow().len() as u32
122    }
123
124    #[inline(always)]
125    fn set(&self, key: Self::Key, value: Self::Value) {
126        self.borrow_mut().insert(key, value);
127    }
128
129    #[inline(always)]
130    fn has(&self, key: Self::Key) -> bool {
131        self.borrow().contains_key(&key)
132    }
133
134    #[inline(always)]
135    fn clear(&self) {
136        self.borrow_mut().clear()
137    }
138
139    #[inline(always)]
140    fn delete(&self, key: Self::Key) -> bool {
141        self.borrow_mut().shift_remove(&key).is_some()
142    }
143}
144
145/// Usage:
146/// ```rust
147/// pub(crate) struct TestBindingMaplike {
148///     // maplike<DOMString, long>
149///     internal: DomRefCell<IndexMap<DOMString, i32>>,
150/// }
151/// impl Maplike for TestBindingSetlike {
152///     type Key = DOMString;
153///     type Value = i32;
154///     maplike!(self, internal);
155/// }
156/// ```
157#[macro_export]
158macro_rules! maplike {
159    ( $self:ident, $internal:ident ) => {
160        #[inline(always)]
161        fn get_index(&$self, index: u32) -> Option<(Self::Key, Self::Value)> {
162            $self.$internal.get_index(index)
163        }
164
165        #[inline(always)]
166        fn get(&$self, key: Self::Key) -> Option<Self::Value> {
167            $self.$internal.get(key)
168        }
169
170        #[inline(always)]
171        fn size(&$self) -> u32 {
172            $self.$internal.size()
173        }
174
175        #[inline(always)]
176        fn set(&$self, key: Self::Key, value: Self::Value) {
177            $self.$internal.set(key, value)
178        }
179
180        #[inline(always)]
181        fn has(&$self, key: Self::Key) -> bool {
182            $self.$internal.has(key)
183        }
184
185        #[inline(always)]
186        fn clear(&$self) {
187            $self.$internal.clear()
188        }
189
190        #[inline(always)]
191        fn delete(&$self, key: Self::Key) -> bool {
192            $self.$internal.delete(key)
193        }
194    };
195}