use {
super::{Parse, ParserContext},
crate::{
domain::{
at_rules::font_feature_values::FontFeatureValuesDeclaration,
Atom,
},
CustomParseError,
},
cssparser::{
AtRuleParser,
CowRcStr,
DeclarationListParser,
DeclarationParser,
ParseError,
Parser,
ToCss,
},
};
pub(crate) struct FontFeatureValuesDeclarationsParser<'a, T: 'a + Parse + ToCss>
{
context: &'a ParserContext,
declarations: &'a mut Vec<FontFeatureValuesDeclaration<T>>,
}
impl<'a, 'i, T: 'a + Parse + ToCss> AtRuleParser<'i>
for FontFeatureValuesDeclarationsParser<'a, T>
{
type Prelude = ();
type AtRule = ();
type Error = CustomParseError<'i>;
}
impl<'a, 'i, T: 'a + Parse + ToCss> DeclarationParser<'i>
for FontFeatureValuesDeclarationsParser<'a, T>
{
type Declaration = ();
type Error = CustomParseError<'i>;
fn parse_value<'t>(
&mut self,
name: CowRcStr<'i>,
input: &mut Parser<'i, 't>,
) -> Result<(), ParseError<'i, CustomParseError<'i>>> {
let fontFeatureValuesDeclaration = FontFeatureValuesDeclaration {
name: Atom::from(&*name),
value: input.parse_entirely(|i| T::parse(self.context, i))?,
};
self.update_or_push(fontFeatureValuesDeclaration);
Ok(())
}
}
impl<'a, 'b: 'a, T: 'a + Parse + ToCss>
FontFeatureValuesDeclarationsParser<'a, T>
{
pub(crate) fn parseBlock<'i, 't>(
input: &mut Parser<'i, 't>,
context: &'a ParserContext,
declarations: &'a mut Vec<FontFeatureValuesDeclaration<T>>,
) -> Result<(), ParseError<'i, CustomParseError<'i>>> {
let parser = Self {
context,
declarations,
};
let iter = DeclarationListParser::new(input, parser);
for possiblePreciseParseError in iter {
if let Err(msg) = possiblePreciseParseError {
return Err(msg.0);
}
}
Ok(())
}
fn update_or_push(
&mut self,
newDeclaration: FontFeatureValuesDeclaration<T>,
) {
let declarations = &mut self.declarations;
let position = declarations.iter().position(|thisDeclaration| {
thisDeclaration.name == newDeclaration.name
});
if let Some(index) = position {
declarations[index].value = newDeclaration.value;
} else {
declarations.push(newDeclaration);
}
}
}