use {
super::{
at_rules::VendorPrefixedAtRule,
CssRule::{self},
HasCssRules,
RulesMutateError::{self},
},
cssparser::ToCss,
std::fmt,
};
#[derive(Default, Debug, Clone)]
pub struct CssRules(pub Vec<CssRule>);
impl ToCss for CssRules {
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
for cssRule in self.0.iter() {
cssRule.to_css(dest)?;
}
Ok(())
}
}
impl HasCssRules for CssRules {
#[inline(always)]
fn css_rules(&self) -> &CssRules {
self
}
#[inline(always)]
fn css_rules_mut(&mut self) -> &mut CssRules {
self
}
#[inline(always)]
fn css_rules_slice(&self) -> &[CssRule] {
&self.0[..]
}
#[inline(always)]
fn css_rules_vec(&self) -> &Vec<CssRule> {
&self.0
}
#[inline(always)]
fn css_rules_vec_mut(&mut self) -> &mut Vec<CssRule> {
&mut self.0
}
}
impl CssRules {
#[inline(always)]
pub fn vendor_prefix_at_rules<
AtRule: VendorPrefixedAtRule,
CssRuleMatcher: Fn(&CssRule) -> Option<&AtRule>,
VendorPrefixer: Fn(usize, &AtRule) -> Vec<CssRule>,
>(
&mut self,
remove_unprefixed_at_rule: bool,
css_rule_matcher: CssRuleMatcher,
vendor_prefixer: VendorPrefixer,
) {
let mut index = 0;
while index < self.0.len() {
let newCssRulesToInsert = match css_rule_matcher(unsafe {
self.0.get_unchecked(index)
}) {
None => None,
Some(atRule) => {
if atRule.isNotVendorPrefixed() {
Some(vendor_prefixer(index, atRule))
} else {
None
}
}
};
index += if let Some(mut newCssRulesToInsert) = newCssRulesToInsert
{
let indexIncrement = newCssRulesToInsert.len();
for newCssRuleToInsert in newCssRulesToInsert.drain(..) {
self.css_rules_vec_mut().insert(index, newCssRuleToInsert);
}
if remove_unprefixed_at_rule {
self.css_rules_vec_mut().remove(index + indexIncrement);
indexIncrement
} else {
indexIncrement + 1
}
} else {
1
};
}
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn only_namespace_or_import(&self) -> bool {
use self::CssRule::*;
self.0.iter().all(|r| match *r {
Namespace(..) | Import(..) => true,
_ => false,
})
}
pub fn remove_rule(
&mut self,
index: usize,
) -> Result<(), RulesMutateError> {
use self::{CssRule::Namespace, RulesMutateError::*};
if index >= self.0.len() {
return Err(IndexSize);
}
{
let rule = &self.0[index];
if let Namespace(..) = *rule {
if !self.only_namespace_or_import() {
return Err(InvalidState);
}
}
}
self.0.remove(index);
Ok(())
}
}