diff options
Diffstat (limited to 'components/style/parsing_utils.rs')
-rw-r--r-- | components/style/parsing_utils.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/components/style/parsing_utils.rs b/components/style/parsing_utils.rs new file mode 100644 index 00000000000..3afd7ba0353 --- /dev/null +++ b/components/style/parsing_utils.rs @@ -0,0 +1,81 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +use std::ascii::StrAsciiExt; +use cssparser::ast::{ComponentValue, Ident, Comma, SkipWhitespaceIterable, SkipWhitespaceIterator}; + + +pub fn one_component_value<'a>(input: &'a [ComponentValue]) -> Result<&'a ComponentValue, ()> { + let mut iter = input.skip_whitespace(); + match iter.next() { + Some(value) => if iter.next().is_none() { Ok(value) } else { Err(()) }, + None => Err(()) + } +} + + +pub fn get_ident_lower(component_value: &ComponentValue) -> Result<String, ()> { + match component_value { + &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) +} |