aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/style/parsing_utils.rs
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2014-08-16 12:24:34 +0100
committerSimon Sapin <simon.sapin@exyr.org>2014-08-16 12:24:34 +0100
commit444ff8425922d350120eb5412c96c26060b55c88 (patch)
tree53d7e8a5d5c163d084117944bd3fdd4eb71de13d /src/components/style/parsing_utils.rs
parentba592364b7655b66a4d384e8deabcde88755825f (diff)
parent4ca385ba10faeaf32b5aeb2cbd293542c8d8a3c9 (diff)
downloadservo-444ff8425922d350120eb5412c96c26060b55c88.tar.gz
servo-444ff8425922d350120eb5412c96c26060b55c88.zip
Merge pull request #3078 from SimonSapin/style-cleanup
Various refactoring and fixes in the style crate
Diffstat (limited to 'src/components/style/parsing_utils.rs')
-rw-r--r--src/components/style/parsing_utils.rs72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/components/style/parsing_utils.rs b/src/components/style/parsing_utils.rs
index df355629971..3afd7ba0353 100644
--- a/src/components/style/parsing_utils.rs
+++ b/src/components/style/parsing_utils.rs
@@ -4,18 +4,78 @@
use std::ascii::StrAsciiExt;
-use cssparser::ast::{ComponentValue, Ident, SkipWhitespaceIterable};
+use cssparser::ast::{ComponentValue, Ident, Comma, SkipWhitespaceIterable, SkipWhitespaceIterator};
-pub fn one_component_value<'a>(input: &'a [ComponentValue]) -> Option<&'a ComponentValue> {
+pub fn one_component_value<'a>(input: &'a [ComponentValue]) -> Result<&'a ComponentValue, ()> {
let mut iter = input.skip_whitespace();
- iter.next().filtered(|_| iter.next().is_none())
+ match iter.next() {
+ Some(value) => if iter.next().is_none() { Ok(value) } else { Err(()) },
+ None => Err(())
+ }
}
-pub fn get_ident_lower(component_value: &ComponentValue) -> Option<String> {
+pub fn get_ident_lower(component_value: &ComponentValue) -> Result<String, ()> {
match component_value {
- &Ident(ref value) => Some(value.as_slice().to_ascii_lower()),
- _ => None,
+ &Ident(ref value) => Ok(value.as_slice().to_ascii_lower()),
+ _ => Err(()),
+ }
+}
+
+
+pub struct BufferedIter<E, I> {
+ iter: I,
+ buffer: Option<E>,
+}
+
+impl<E, I: Iterator<E>> BufferedIter<E, I> {
+ pub fn new(iter: I) -> BufferedIter<E, I> {
+ BufferedIter {
+ iter: iter,
+ buffer: None,
+ }
+ }
+
+ #[inline]
+ pub fn push_back(&mut self, value: E) {
+ assert!(self.buffer.is_none());
+ self.buffer = Some(value);
+ }
+}
+
+impl<E, I: Iterator<E>> Iterator<E> for BufferedIter<E, I> {
+ #[inline]
+ fn next(&mut self) -> Option<E> {
+ if self.buffer.is_some() {
+ self.buffer.take()
+ }
+ else {
+ self.iter.next()
+ }
+ }
+}
+
+pub type ParserIter<'a, 'b> = &'a mut BufferedIter<&'b ComponentValue, SkipWhitespaceIterator<'b>>;
+
+
+#[inline]
+pub fn parse_slice_comma_separated<T>(input: &[ComponentValue],
+ parse_one: |ParserIter| -> Result<T, ()>)
+ -> Result<Vec<T>, ()> {
+ parse_comma_separated(&mut BufferedIter::new(input.skip_whitespace()), parse_one)
+}
+
+#[inline]
+pub fn parse_comma_separated<T>(iter: ParserIter,
+ parse_one: |ParserIter| -> Result<T, ()>)
+ -> Result<Vec<T>, ()> {
+ let mut values = vec![try!(parse_one(iter))];
+ for component_value in iter {
+ match component_value {
+ &Comma => values.push(try!(parse_one(iter))),
+ _ => return Err(())
+ }
}
+ Ok(values)
}