style: Implement OrderedMapIterator

This commit is contained in:
Fernando Jiménez Moreno 2017-08-04 14:16:43 +02:00
parent fd1f14a41e
commit ff1e701fa6
2 changed files with 58 additions and 20 deletions

View file

@ -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 {

View file

@ -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,
}; };