Skip to content

Instantly share code, notes, and snippets.

@emilio
Created November 1, 2018 02:09
Show Gist options
  • Save emilio/421418d12864929a7d0d9c4a98ff7ccb to your computer and use it in GitHub Desktop.
Save emilio/421418d12864929a7d0d9c4a98ff7ccb to your computer and use it in GitHub Desktop.
diff --git a/servo/components/style_derive/to_css.rs b/servo/components/style_derive/to_css.rs
index a5811471cb1d..edb63b7c1ae8 100644
--- a/servo/components/style_derive/to_css.rs
+++ b/servo/components/style_derive/to_css.rs
@@ -5,24 +5,30 @@
use cg;
use darling::util::Override;
use quote::{ToTokens, Tokens};
use syn::{self, Data, Path, WhereClause};
use synstructure::{BindingInfo, Structure, VariantInfo};
pub fn derive(mut input: syn::DeriveInput) -> Tokens {
let mut where_clause = input.generics.where_clause.take();
+ let input_attrs = cg::parse_input_attrs::<CssInputAttrs>(&input);
for param in input.generics.type_params() {
+ if let Some(ref bounds) = input_attrs.extra_bounds {
+ cg::add_predicate(
+ &mut where_clause,
+ parse_quote!(#param: #bounds),
+ );
+ }
cg::add_predicate(
&mut where_clause,
parse_quote!(#param: ::style_traits::ToCss),
);
}
- let input_attrs = cg::parse_input_attrs::<CssInputAttrs>(&input);
if let Data::Enum(_) = input.data {
assert!(
input_attrs.function.is_none(),
"#[css(function)] is not allowed on enums"
);
assert!(!input_attrs.comma, "#[css(comma)] is not allowed on enums");
}
@@ -144,16 +150,25 @@ fn derive_variant_fields_expr(
let mut expr = quote! { ::style_traits::ToCss::to_css(#first, dest) };
if let Some(condition) = attrs.skip_if {
expr = quote! {
if !#condition(#first) {
#expr
}
}
}
+
+ if let Some(condition) = attrs.skip_if_self {
+ expr = quote! {
+ if !#condition(self) {
+ #expr
+ }
+ }
+ }
+
return expr;
}
let mut expr = derive_single_field_expr(first, attrs, where_clause);
for (binding, attrs) in iter {
derive_single_field_expr(binding, attrs, where_clause).to_tokens(&mut expr)
}
@@ -212,27 +227,36 @@ fn derive_single_field_expr(
if let Some(condition) = attrs.skip_if {
expr = quote! {
if !#condition(#field) {
#expr
}
}
}
+ if let Some(condition) = attrs.skip_if_self {
+ expr = quote! {
+ if !#condition(self) {
+ #expr
+ }
+ }
+ }
+
expr
}
#[darling(attributes(css), default)]
#[derive(Default, FromDeriveInput)]
pub struct CssInputAttrs {
pub derive_debug: bool,
// Here because structs variants are also their whole type definition.
pub function: Option<Override<String>>,
// Here because structs variants are also their whole type definition.
pub comma: bool,
+ pub extra_bounds: Option<Path>,
}
#[darling(attributes(css), default)]
#[derive(Default, FromVariant)]
pub struct CssVariantAttrs {
pub function: Option<Override<String>>,
// Here because structs variants are also their whole type definition.
pub derive_debug: bool,
@@ -246,9 +270,10 @@ pub struct CssVariantAttrs {
#[derive(Default, FromField)]
pub struct CssFieldAttrs {
pub if_empty: Option<String>,
pub field_bound: bool,
pub iterable: bool,
pub skip: bool,
pub represents_keyword: bool,
pub skip_if: Option<Path>,
+ pub skip_if_self: Option<Path>,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment