diff options
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) } |