script_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 js::conversions::ToJSValConvertible;
8
9use crate::iterable::Iterable;
10
11/// Every Setlike dom_struct must implement this to provide access to underlying storage
12/// so codegen can automatically generate all setlike methods
13///
14/// In case you use a type that implements Setlike as underlying storage it's recommended to use `setlike` macro.
15// In webidl: `setlike<Key>`
16pub trait Setlike {
17    /// The type of the key of the set.
18    type Key: ToJSValConvertible + Clone; // clone is for impl<T: Setlike> Maplike for T
19
20    fn get_index(&self, index: u32) -> Option<Self::Key>;
21
22    fn size(&self) -> u32;
23    fn add(&self, key: Self::Key);
24    fn has(&self, key: Self::Key) -> bool;
25    fn clear(&self);
26    fn delete(&self, key: Self::Key) -> bool;
27}
28
29// we can only have one iterable for T
30// so we have impl<T: Maplike> Iterable for T
31// and minimal:
32impl<T: Setlike> Maplike for T {
33    type Key = <T as Setlike>::Key;
34
35    type Value = <T as Setlike>::Key;
36
37    #[inline]
38    fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)> {
39        self.get_index(index).map(|k| (k.clone(), k))
40    }
41
42    fn get(&self, _key: Self::Key) -> Option<Self::Value> {
43        unimplemented!()
44    }
45
46    #[inline]
47    fn size(&self) -> u32 {
48        self.size()
49    }
50
51    fn set(&self, _key: Self::Key, _value: Self::Value) {
52        unimplemented!()
53    }
54
55    fn has(&self, _key: Self::Key) -> bool {
56        unimplemented!()
57    }
58
59    fn clear(&self) {
60        unimplemented!()
61    }
62
63    fn delete(&self, _key: Self::Key) -> bool {
64        unimplemented!()
65    }
66}
67
68/// Every Maplike dom_struct must implement this
69/// to provide access to underlying storage
70/// so codegen can automatically generate all maplike methods
71///
72/// In case you use a type that implements Maplike as underlying storage it's recommended to use `maplike` macro.
73// In webidl: `maplike<Key, Value>`
74pub trait Maplike {
75    /// The type of the key of the map.
76    type Key: ToJSValConvertible;
77    /// The type of the value of the map.
78    type Value: ToJSValConvertible;
79
80    fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)>;
81
82    fn get(&self, key: Self::Key) -> Option<Self::Value>;
83    fn size(&self) -> u32;
84    fn set(&self, key: Self::Key, value: Self::Value);
85    fn has(&self, key: Self::Key) -> bool;
86    fn clear(&self);
87    fn delete(&self, key: Self::Key) -> bool;
88}
89
90impl<T: Maplike> Iterable for T {
91    type Key = T::Key;
92
93    type Value = T::Value;
94
95    #[inline]
96    fn get_iterable_length(&self) -> u32 {
97        self.size()
98    }
99
100    #[inline]
101    fn get_value_at_index(&self, index: u32) -> <T as Maplike>::Value {
102        // SAFETY: we are checking bounds manually
103        self.get_index(index).unwrap().1
104    }
105
106    #[inline]
107    fn get_key_at_index(&self, index: u32) -> <T as Maplike>::Key {
108        // SAFETY: we are checking bounds manually
109        self.get_index(index).unwrap().0
110    }
111}