/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script_bindings/like.rs
237 строк
7 KB
Josh Matthews
script: Use AtomicRefCell for CustomStateSet internal set. (#46758)
24 июл 2026, 08:21
Не верифицирован
24 июл 2026, 08:21
25ec51f
Код
Авторство
О чём код?
/* 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 std::hash::Hash; use atomic_refcell::AtomicRefCell; use indexmap::{IndexMap, IndexSet}; use js::context::JSContext; use js::conversions::ToJSValConvertible; use crate::cell::DomRefCell; 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<Key>` pub trait Setlike { /// The type of the key of the set. type Key: ToJSValConvertible + Clone; // clone is for impl<T: Setlike> Maplike for T fn get_index(&self, cx: &mut JSContext, index: u32) -> Option<Self::Key>; fn size(&self, cx: &mut JSContext) -> u32; fn add(&self, cx: &mut JSContext, key: Self::Key); fn has(&self, cx: &mut JSContext, key: Self::Key) -> bool; fn clear(&self, cx: &mut JSContext); fn delete(&self, cx: &mut JSContext, key: Self::Key) -> bool; } // we can only have one iterable for T // so we have impl<T: Maplike> Iterable for T // and minimal: impl<T: Setlike> Maplike for T { type Key = <T as Setlike>::Key; type Value = <T as Setlike>::Key; #[inline] fn get_index(&self, cx: &mut JSContext, index: u32) -> Option<(Self::Key, Self::Value)> { self.get_index(cx, index).map(|k| (k.clone(), k)) } fn get(&self, _cx: &mut JSContext, _key: Self::Key) -> Option<Self::Value> { unimplemented!() } #[inline] fn size(&self, cx: &mut JSContext) -> u32 { self.size(cx) } fn set(&self, _cx: &mut JSContext, _key: Self::Key, _value: Self::Value) { unimplemented!() } fn has(&self, _cx: &mut JSContext, _key: Self::Key) -> bool { unimplemented!() } fn clear(&self, _cx: &mut JSContext) { unimplemented!() } fn delete(&self, _cx: &mut JSContext, _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<Key, Value>` 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, cx: &mut JSContext, index: u32) -> Option<(Self::Key, Self::Value)>; fn get(&self, cx: &mut JSContext, key: Self::Key) -> Option<Self::Value>; fn size(&self, cx: &mut JSContext) -> u32; fn set(&self, cx: &mut JSContext, key: Self::Key, value: Self::Value); fn has(&self, cx: &mut JSContext, key: Self::Key) -> bool; fn clear(&self, cx: &mut JSContext); fn delete(&self, cx: &mut JSContext, key: Self::Key) -> bool; } impl<T: Maplike> Iterable for T { type Key = T::Key; type Value = T::Value; #[inline] fn get_iterable_length(&self, cx: &mut JSContext) -> u32 { self.size(cx) } #[inline] fn get_value_at_index(&self, cx: &mut JSContext, index: u32) -> <T as Maplike>::Value { // We are checking bounds manually self.get_index(cx, index).unwrap().1 } #[inline] fn get_key_at_index(&self, cx: &mut JSContext, index: u32) -> <T as Maplike>::Key { // We are checking bounds manually self.get_index(cx, index).unwrap().0 } } impl<K, V> Maplike for DomRefCell<IndexMap<K, V>> where K: ToJSValConvertible + Eq + PartialEq + Hash + Clone, V: ToJSValConvertible + Clone, { type Key = K; type Value = V; #[inline(always)] fn get_index(&self, _cx: &mut JSContext, index: u32) -> Option<(Self::Key, Self::Value)> { self.borrow() .get_index(index as usize) .map(|(k, v)| (k.to_owned(), v.to_owned())) } #[inline(always)] fn get(&self, _cx: &mut JSContext, key: Self::Key) -> Option<Self::Value> { self.borrow().get(&key).cloned() } #[inline(always)] fn size(&self, _cx: &mut JSContext) -> u32 { self.borrow().len() as u32 } #[inline(always)] fn set(&self, _cx: &mut JSContext, key: Self::Key, value: Self::Value) { self.borrow_mut().insert(key, value); } #[inline(always)] fn has(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow().contains_key(&key) } #[inline(always)] fn clear(&self, _cx: &mut JSContext) { self.borrow_mut().clear() } #[inline(always)] fn delete(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow_mut().shift_remove(&key).is_some() } } impl<K> Setlike for DomRefCell<IndexSet<K>> where K: ToJSValConvertible + Eq + PartialEq + Hash + Clone, { type Key = K; #[inline(always)] fn get_index(&self, _cx: &mut JSContext, index: u32) -> Option<Self::Key> { self.borrow().get_index(index as usize).cloned() } #[inline(always)] fn size(&self, _cx: &mut JSContext) -> u32 { self.borrow().len() as u32 } #[inline(always)] fn add(&self, _cx: &mut JSContext, key: Self::Key) { self.borrow_mut().insert(key); } #[inline(always)] fn has(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow().contains(&key) } #[inline(always)] fn clear(&self, _cx: &mut JSContext) { self.borrow_mut().clear() } #[inline(always)] fn delete(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow_mut().shift_remove(&key) } } impl<K> Setlike for AtomicRefCell<IndexSet<K>> where K: ToJSValConvertible + Eq + PartialEq + Hash + Clone, { type Key = K; #[inline(always)] fn get_index(&self, _cx: &mut JSContext, index: u32) -> Option<Self::Key> { self.borrow().get_index(index as usize).cloned() } #[inline(always)] fn size(&self, _cx: &mut JSContext) -> u32 { self.borrow().len() as u32 } #[inline(always)] fn add(&self, _cx: &mut JSContext, key: Self::Key) { self.borrow_mut().insert(key); } #[inline(always)] fn has(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow().contains(&key) } #[inline(always)] fn clear(&self, _cx: &mut JSContext) { self.borrow_mut().clear() } #[inline(always)] fn delete(&self, _cx: &mut JSContext, key: Self::Key) -> bool { self.borrow_mut().shift_remove(&key) } }