/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Implementation of `setlike<...>` and `maplike<..., ...>` WebIDL declarations. use js::conversions::ToJSValConvertible; use crate::iterable::Iterable; /// Every Setlike dom_struct must implement this to provide access to underlying storage /// so codegen can automatically generate all setlike methods /// /// In case you use a type that implements Setlike as underlying storage it's recommended to use `setlike` macro. // In webidl: `setlike` pub trait Setlike { /// The type of the key of the set. type Key: ToJSValConvertible + Clone; // clone is for impl Maplike for T fn get_index(&self, index: u32) -> Option; fn size(&self) -> u32; fn add(&self, key: Self::Key); fn has(&self, key: Self::Key) -> bool; fn clear(&self); fn delete(&self, key: Self::Key) -> bool; } // we can only have one iterable for T // so we have impl Iterable for T // and minimal: impl Maplike for T { type Key = ::Key; type Value = ::Key; #[inline] fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)> { self.get_index(index).map(|k| (k.clone(), k)) } fn get(&self, _key: Self::Key) -> Option { unimplemented!() } #[inline] fn size(&self) -> u32 { self.size() } fn set(&self, _key: Self::Key, _value: Self::Value) { unimplemented!() } fn has(&self, _key: Self::Key) -> bool { unimplemented!() } fn clear(&self) { unimplemented!() } fn delete(&self, _key: Self::Key) -> bool { unimplemented!() } } /// Every Maplike dom_struct must implement this /// to provide access to underlying storage /// so codegen can automatically generate all maplike methods /// /// In case you use a type that implements Maplike as underlying storage it's recommended to use `maplike` macro. // In webidl: `maplike` pub trait Maplike { /// The type of the key of the map. type Key: ToJSValConvertible; /// The type of the value of the map. type Value: ToJSValConvertible; fn get_index(&self, index: u32) -> Option<(Self::Key, Self::Value)>; fn get(&self, key: Self::Key) -> Option; fn size(&self) -> u32; fn set(&self, key: Self::Key, value: Self::Value); fn has(&self, key: Self::Key) -> bool; fn clear(&self); fn delete(&self, key: Self::Key) -> bool; } impl Iterable for T { type Key = T::Key; type Value = T::Value; #[inline] fn get_iterable_length(&self) -> u32 { self.size() } #[inline] fn get_value_at_index(&self, index: u32) -> ::Value { // SAFETY: we are checking bounds manually self.get_index(index).unwrap().1 } #[inline] fn get_key_at_index(&self, index: u32) -> ::Key { // SAFETY: we are checking bounds manually self.get_index(index).unwrap().0 } }