mirror of
https://github.com/servo/servo.git
synced 2025-06-25 17:44:33 +01:00
style: Implement OrderedMapIterator
This commit is contained in:
parent
fd1f14a41e
commit
ff1e701fa6
2 changed files with 58 additions and 20 deletions
|
@ -14,7 +14,7 @@ use selectors::parser::SelectorParseError;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::collections::{HashMap, hash_map, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use style_traits::{HasViewportPercentage, ToCss, StyleParseError, ParseError};
|
use style_traits::{HasViewportPercentage, ToCss, StyleParseError, ParseError};
|
||||||
|
@ -106,9 +106,9 @@ pub struct OrderedMap<K, V>
|
||||||
where
|
where
|
||||||
K: Eq + Hash + Clone,
|
K: Eq + Hash + Clone,
|
||||||
{
|
{
|
||||||
/// Custom property name index.
|
/// Key index.
|
||||||
index: Vec<K>,
|
index: Vec<K>,
|
||||||
/// Computed values indexed by custom property name.
|
/// Key-value map.
|
||||||
values: HashMap<K, V>,
|
values: HashMap<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ impl<K, V> OrderedMap<K, V>
|
||||||
where
|
where
|
||||||
K: Eq + Hash + Clone,
|
K: Eq + Hash + Clone,
|
||||||
{
|
{
|
||||||
/// Creates a new custom properties map.
|
/// Creates a new ordered map.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
OrderedMap {
|
OrderedMap {
|
||||||
index: Vec::new(),
|
index: Vec::new(),
|
||||||
|
@ -124,36 +124,41 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a computed value if it has not previously been inserted.
|
/// Insert a new key-value pair.
|
||||||
pub fn insert(&mut self, name: K, value: V) {
|
pub fn insert(&mut self, key: K, value: V) {
|
||||||
debug_assert!(!self.index.contains(&name));
|
if !self.values.contains_key(&key) {
|
||||||
self.index.push(name.clone());
|
self.index.push(key.clone());
|
||||||
self.values.insert(name, value);
|
}
|
||||||
|
self.values.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom property computed value getter by name.
|
/// Get a value given its key.
|
||||||
pub fn get(&self, name: &K) -> Option<&V> {
|
pub fn get(&self, key: &K) -> Option<&V> {
|
||||||
let value = self.values.get(name);
|
let value = self.values.get(key);
|
||||||
debug_assert_eq!(value.is_some(), self.index.contains(name));
|
debug_assert_eq!(value.is_some(), self.index.contains(key));
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the name of a custom property given its list index.
|
/// Get the key located at the given index.
|
||||||
pub fn get_key_at(&self, index: u32) -> Option<&K> {
|
pub fn get_key_at(&self, index: u32) -> Option<&K> {
|
||||||
self.index.get(index as usize)
|
self.index.get(index as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator for custom properties computed values.
|
/// Get an ordered map iterator.
|
||||||
pub fn iter(&self) -> hash_map::Iter<K, V> {
|
pub fn iter<'a>(&'a self) -> OrderedMapIterator<'a, K, V> {
|
||||||
self.values.iter()
|
OrderedMapIterator {
|
||||||
|
inner: self,
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the count of custom properties computed values.
|
/// Get the count of items in the map.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
debug_assert_eq!(self.values.len(), self.index.len());
|
debug_assert_eq!(self.values.len(), self.index.len());
|
||||||
self.values.len()
|
self.values.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove an item given its key.
|
||||||
fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
|
fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
|
||||||
where
|
where
|
||||||
K: Borrow<Q>,
|
K: Borrow<Q>,
|
||||||
|
@ -168,6 +173,39 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator for OrderedMap.
|
||||||
|
///
|
||||||
|
/// The iteration order is determined by the order that the values are
|
||||||
|
/// added to the key-value map.
|
||||||
|
pub struct OrderedMapIterator<'a, K, V>
|
||||||
|
where
|
||||||
|
K: 'a + Eq + Hash + Clone, V: 'a,
|
||||||
|
{
|
||||||
|
/// The OrderedMap itself.
|
||||||
|
inner: &'a OrderedMap<K, V>,
|
||||||
|
/// The position of the iterator.
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, K, V> Iterator for OrderedMapIterator<'a, K, V>
|
||||||
|
where
|
||||||
|
K: Eq + Hash + Clone,
|
||||||
|
{
|
||||||
|
type Item = (&'a K, &'a V);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let ref index = self.inner.index;
|
||||||
|
if self.pos >= index.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ref key = index[index.len() - self.pos - 1];
|
||||||
|
self.pos += 1;
|
||||||
|
let value = self.inner.values.get(key).unwrap();
|
||||||
|
Some((key, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ComputedValue {
|
impl ComputedValue {
|
||||||
fn empty() -> ComputedValue {
|
fn empty() -> ComputedValue {
|
||||||
ComputedValue {
|
ComputedValue {
|
||||||
|
|
|
@ -3519,7 +3519,7 @@ pub extern "C" fn Servo_GetCustomPropertyValue(computed_values: ServoStyleContex
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = unsafe { Atom::from((&*name)) };
|
let name = unsafe { Atom::from((&*name)) };
|
||||||
let computed_value = match custom_properties.get_computed_value(&name) {
|
let computed_value = match custom_properties.get(&name) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
@ -3545,7 +3545,7 @@ pub extern "C" fn Servo_GetCustomPropertyNameAt(computed_values: ServoStyleConte
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let property_name = match custom_properties.get_name_at(index) {
|
let property_name = match custom_properties.get_key_at(index) {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue