mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use darling in style_derive
This allows use to handle #[css] in a way simpler fashion.
This commit is contained in:
parent
49a5ceca9b
commit
17d97cf87b
5 changed files with 63 additions and 42 deletions
|
@ -10,6 +10,7 @@ path = "lib.rs"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
darling = "0.2"
|
||||
quote = "0.3.15"
|
||||
syn = { version = "0.11", features = ["visit"] }
|
||||
synstructure = "0.5.2"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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 darling::FromVariant;
|
||||
use quote::Tokens;
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
|
@ -136,6 +137,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_variant_attrs<A>(variant: &Variant) -> A
|
||||
where
|
||||
A: FromVariant,
|
||||
{
|
||||
match A::from_variant(variant) {
|
||||
Ok(attrs) => attrs,
|
||||
Err(e) => panic!("failed to parse attributes: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ref_pattern<'a>(
|
||||
name: &Ident,
|
||||
variant: &'a Variant,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
#[macro_use] extern crate darling;
|
||||
extern crate proc_macro;
|
||||
#[macro_use] extern crate quote;
|
||||
extern crate syn;
|
||||
|
|
|
@ -16,47 +16,8 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
|||
let style = synstructure::BindStyle::Ref.into();
|
||||
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
|
||||
let mut identifier = to_css_identifier(variant.ident.as_ref());
|
||||
let mut css_attrs = variant.attrs.iter().filter(|attr| attr.name() == "css");
|
||||
let (is_function, use_comma) = css_attrs.next().map_or((false, false), |attr| {
|
||||
match attr.value {
|
||||
syn::MetaItem::List(ref ident, ref items) if ident.as_ref() == "css" => {
|
||||
let mut nested = items.iter();
|
||||
let mut is_function = false;
|
||||
let mut use_comma = false;
|
||||
for attr in nested.by_ref() {
|
||||
match *attr {
|
||||
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref ident)) => {
|
||||
match ident.as_ref() {
|
||||
"function" => {
|
||||
if is_function {
|
||||
panic!("repeated `#[css(function)]` attribute");
|
||||
}
|
||||
is_function = true;
|
||||
},
|
||||
"comma" => {
|
||||
if use_comma {
|
||||
panic!("repeated `#[css(comma)]` attribute");
|
||||
}
|
||||
use_comma = true;
|
||||
},
|
||||
_ => panic!("only `#[css(function | comma)]` is supported for now"),
|
||||
}
|
||||
},
|
||||
_ => panic!("only `#[css(<ident...>)]` is supported for now"),
|
||||
}
|
||||
}
|
||||
if nested.next().is_some() {
|
||||
panic!("only `#[css()]` or `#[css(<ident>)]` is supported for now")
|
||||
}
|
||||
(is_function, use_comma)
|
||||
},
|
||||
_ => panic!("only `#[css(...)]` is supported for now"),
|
||||
}
|
||||
});
|
||||
if css_attrs.next().is_some() {
|
||||
panic!("only a single `#[css(...)]` attribute is supported for now");
|
||||
}
|
||||
let separator = if use_comma { ", " } else { " " };
|
||||
let css_attrs = cg::parse_variant_attrs::<CssAttrs>(variant);
|
||||
let separator = if css_attrs.comma { ", " } else { " " };
|
||||
let mut expr = if !bindings.is_empty() {
|
||||
let mut expr = quote! {};
|
||||
for binding in bindings {
|
||||
|
@ -80,7 +41,7 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
|||
::std::fmt::Write::write_str(dest, #identifier)
|
||||
}
|
||||
};
|
||||
if is_function {
|
||||
if css_attrs.function {
|
||||
identifier.push_str("(");
|
||||
expr = quote! {
|
||||
::std::fmt::Write::write_str(dest, #identifier)?;
|
||||
|
@ -107,6 +68,13 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, FromVariant)]
|
||||
#[darling(attributes(css), default)]
|
||||
struct CssAttrs {
|
||||
function: bool,
|
||||
comma: bool,
|
||||
}
|
||||
|
||||
/// Transforms "FooBar" to "foo-bar".
|
||||
///
|
||||
/// If the first Camel segment is "Moz" or "Webkit", the result string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue