style: Reduce code size of shorthand serialization

Differential Revision: https://phabricator.services.mozilla.com/D118835
This commit is contained in:
Emilio Cobos Álvarez 2023-05-22 10:00:33 +02:00 committed by Oriol Brufau
parent 58e9ee4d1e
commit 85b7a60a69
3 changed files with 39 additions and 40 deletions

View file

@ -1197,7 +1197,7 @@ pub fn append_declaration_value<'a, 'b: 'a>(
AppendableValue::Css(css) => dest.write_str(css),
AppendableValue::Declaration(decl) => decl.to_css(dest),
AppendableValue::DeclarationsForShorthand(shorthand, decls) => {
shorthand.longhands_to_css(decls, &mut CssWriter::new(dest))
shorthand.longhands_to_css(decls, dest)
},
}
}

View file

@ -845,10 +845,7 @@
impl<'a> LonghandsToSerialize<'a> {
/// Tries to get a serializable set of longhands given a set of
/// property declarations.
pub fn from_iter<I>(iter: I) -> Result<Self, ()>
where
I: Iterator<Item=&'a PropertyDeclaration>,
{
pub fn from_iter(iter: impl Iterator<Item = &'a PropertyDeclaration>) -> Result<Self, ()> {
// Define all of the expected variables that correspond to the shorthand
% for sub_property in shorthand.sub_properties:
let mut ${sub_property.ident} =
@ -856,8 +853,8 @@
% endfor
// Attempt to assign the incoming declarations to the expected variables
for longhand in iter {
match *longhand {
for declaration in iter {
match *declaration {
% for sub_property in shorthand.sub_properties:
PropertyDeclaration::${sub_property.camel_case}(ref value) => {
${sub_property.ident} = Some(value)
@ -918,6 +915,14 @@
})
}
/// Try to serialize a given shorthand to a string.
pub fn to_css(declarations: &[&PropertyDeclaration], dest: &mut crate::str::CssStringWriter) -> fmt::Result {
match LonghandsToSerialize::from_iter(declarations.iter().cloned()) {
Ok(longhands) => longhands.to_css(&mut CssWriter::new(dest)),
Err(_) => Ok(())
}
}
${caller.body()}
}
% endif

View file

@ -1471,34 +1471,31 @@ impl ShorthandId {
///
/// Returns an error if writing to the stream fails, or if the declarations
/// do not map to a shorthand.
pub fn longhands_to_css<W>(
pub fn longhands_to_css(
&self,
declarations: &[&PropertyDeclaration],
dest: &mut CssWriter<W>,
) -> fmt::Result
where
W: Write,
{
// TODO(emilio): Save codesize here by using a lookup table on
// ShorthandId instead.
let declarations = declarations.iter().cloned();
match *self {
ShorthandId::All => {
// No need to try to serialize the declarations as the 'all'
// shorthand, since it only accepts CSS-wide keywords (and
// variable references), which will be handled in
// get_shorthand_appendable_value.
Ok(())
}
% for property in data.shorthands_except_all():
ShorthandId::${property.camel_case} => {
match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) {
Ok(longhands) => longhands.to_css(dest),
Err(_) => Ok(())
}
},
% endfor
dest: &mut CssStringWriter,
) -> fmt::Result {
type LonghandsToCssFn = for<'a, 'b> fn(&'a [&'b PropertyDeclaration], &mut CssStringWriter) -> fmt::Result;
fn all_to_css(_: &[&PropertyDeclaration], _: &mut CssStringWriter) -> fmt::Result {
// No need to try to serialize the declarations as the 'all'
// shorthand, since it only accepts CSS-wide keywords (and variable
// references), which will be handled in
// get_shorthand_appendable_value.
Ok(())
}
static LONGHANDS_TO_CSS: [LonghandsToCssFn; ${len(data.shorthands)}] = [
% for shorthand in data.shorthands:
% if shorthand.ident == "all":
all_to_css,
% else:
shorthands::${shorthand.ident}::to_css,
% endif
% endfor
];
LONGHANDS_TO_CSS[*self as usize](declarations, dest)
}
/// Finds and returns an appendable value for the given declarations.
@ -1591,23 +1588,20 @@ impl ShorthandId {
input: &mut Parser<'i, 't>,
) -> Result<(), ParseError<'i>>;
fn unreachable<'i, 't>(
fn parse_all<'i, 't>(
_: &mut SourcePropertyDeclaration,
_: &ParserContext,
_: &mut Parser<'i, 't>
input: &mut Parser<'i, 't>
) -> Result<(), ParseError<'i>> {
unreachable!()
// 'all' accepts no value other than CSS-wide keywords
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
// 'all' accepts no value other than CSS-wide keywords
if *self == ShorthandId::All {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
static PARSE_INTO: [ParseIntoFn; ${len(data.shorthands)}] = [
% for shorthand in data.shorthands:
% if shorthand.ident == "all":
unreachable,
parse_all,
% else:
shorthands::${shorthand.ident}::parse_into,
% endif