Bug 1362914 - Factor out PropertyDeclaration only iterator. r?manishearth draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 19 May 2017 16:40:57 +0900
changeset 581061 3547e3b2db25d2b16e41835db301d29d606fda31
parent 580912 8e98dab5054dd093a37ba20c62cf0523e484cfbd
child 581062 64f9a3fa0350ddafb9df312e31512e29736f19df
push id59757
push userhikezoe@mozilla.com
push dateFri, 19 May 2017 07:56:24 +0000
reviewersmanishearth
bugs1362914
milestone55.0a1
Bug 1362914 - Factor out PropertyDeclaration only iterator. r?manishearth MozReview-Commit-ID: LcyVsynftT2
servo/components/style/properties/declaration_block.rs
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -7,16 +7,17 @@
 #![deny(missing_docs)]
 
 use context::QuirksMode;
 use cssparser::{DeclarationListParser, parse_important};
 use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
 use error_reporting::ParseErrorReporter;
 use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
 use std::fmt;
+use std::slice::Iter;
 use style_traits::ToCss;
 use stylesheets::{CssRuleType, Origin, UrlExtraData};
 use super::*;
 #[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
 
 /// A declaration [importance][importance].
 ///
 /// [importance]: https://drafts.csswg.org/css-cascade/#importance
@@ -49,16 +50,34 @@ pub struct PropertyDeclarationBlock {
     declarations: Vec<(PropertyDeclaration, Importance)>,
 
     /// The number of entries in `self.declaration` with `Importance::Important`
     important_count: usize,
 
     longhands: LonghandIdSet,
 }
 
+/// Iterator for PropertyDeclaration to be generated from PropertyDeclarationBlock.
+#[derive(Clone)]
+pub struct PropertyDeclarationIterator<'a> {
+    iter: Iter<'a, (PropertyDeclaration, Importance)>,
+}
+
+impl<'a> Iterator for PropertyDeclarationIterator<'a> {
+    type Item = &'a PropertyDeclaration;
+    fn next(&mut self) -> Option<&'a PropertyDeclaration> {
+        // we use this function because a closure won't be `Clone`
+        fn get_declaration(dec: &(PropertyDeclaration, Importance))
+            -> &PropertyDeclaration {
+            &dec.0
+        }
+        self.iter.next().map(get_declaration as fn(_) -> _)
+    }
+}
+
 impl fmt::Debug for PropertyDeclarationBlock {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.declarations.fmt(f)
     }
 }
 
 impl PropertyDeclarationBlock {
     /// Returns the number of declarations in the block.
@@ -88,16 +107,23 @@ impl PropertyDeclarationBlock {
         }
     }
 
     /// The declarations in this block
     pub fn declarations(&self) -> &[(PropertyDeclaration, Importance)] {
         &self.declarations
     }
 
+    /// Iterate over only PropertyDeclaration.
+    pub fn declarations_iter(&self) -> PropertyDeclarationIterator {
+        PropertyDeclarationIterator {
+            iter: self.declarations.iter(),
+        }
+    }
+
     /// Returns whether this block contains any declaration with `!important`.
     ///
     /// This is based on the `important_count` counter,
     /// which should be maintained whenever `declarations` is changed.
     // FIXME: make fields private and maintain it here in methods?
     pub fn any_important(&self) -> bool {
         self.important_count > 0
     }
@@ -316,25 +342,20 @@ impl PropertyDeclarationBlock {
             Err(_longhand_or_custom) => {
                 if self.declarations.len() == 1 {
                     self.declarations[0].0.to_css(dest)
                 } else {
                     Err(fmt::Error)
                 }
             }
             Ok(shorthand) => {
-                // we use this function because a closure won't be `Clone`
-                fn get_declaration(dec: &(PropertyDeclaration, Importance))
-                    -> &PropertyDeclaration {
-                    &dec.0
-                }
                 if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
                     return Err(fmt::Error)
                 }
-                let iter = self.declarations.iter().map(get_declaration as fn(_) -> _);
+                let iter = self.declarations_iter();
                 match shorthand.get_shorthand_appendable_value(iter) {
                     Some(AppendableValue::Css { css, .. }) => {
                         dest.write_str(css)
                     },
                     Some(AppendableValue::DeclarationsForShorthand(_, decls)) => {
                         shorthand.longhands_to_css(decls, dest)
                     }
                     _ => Ok(())