diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2014-08-16 12:24:34 +0100 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2014-08-16 12:24:34 +0100 |
commit | 444ff8425922d350120eb5412c96c26060b55c88 (patch) | |
tree | 53d7e8a5d5c163d084117944bd3fdd4eb71de13d /src/components/style/parsing_utils.rs | |
parent | ba592364b7655b66a4d384e8deabcde88755825f (diff) | |
parent | 4ca385ba10faeaf32b5aeb2cbd293542c8d8a3c9 (diff) | |
download | servo-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.rs | 72 |
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) } |