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