Use darling in style_derive

This allows use to handle #[css] in a way simpler fashion.
This commit is contained in:
Anthony Ramine 2017-08-24 00:48:59 +02:00
parent 49a5ceca9b
commit 17d97cf87b
5 changed files with 63 additions and 42 deletions

40
Cargo.lock generated
View file

@ -615,6 +615,36 @@ dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "darling"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "darling_core"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "darling_macro"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "dbghelp-sys" name = "dbghelp-sys"
version = "0.2.0" version = "0.2.0"
@ -1306,6 +1336,11 @@ dependencies = [
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ident_case"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.1.2" version = "0.1.2"
@ -3073,6 +3108,7 @@ dependencies = [
name = "style_derive" name = "style_derive"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3711,6 +3747,9 @@ dependencies = [
"checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6" "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
"checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f" "checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"
"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
"checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
"checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
"checksum darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a86ec160aa0c3dd492dd4a14ec8104ad8f1a9400a820624db857998cc1f80f9"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254" "checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254"
"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
@ -3769,6 +3808,7 @@ dependencies = [
"checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07" "checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07"
"checksum hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "85a372eb692590b3fe014c196c30f9f52d4c42f58cd49dd94caeee1593c9cc37" "checksum hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "85a372eb692590b3fe014c196c30f9f52d4c42f58cd49dd94caeee1593c9cc37"
"checksum hyper_serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbe43f514f80494e9329c9fc47d61b85b167d245685424637a0f4a409177e444" "checksum hyper_serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbe43f514f80494e9329c9fc47d61b85b167d245685424637a0f4a409177e444"
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37" "checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37"
"checksum image 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d95816db758249fe16f23a4e23f1a3a817fe11892dbfd1c5836f625324702158" "checksum image 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d95816db758249fe16f23a4e23f1a3a817fe11892dbfd1c5836f625324702158"
"checksum immeta 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0b9260463a221bfe3f02100c56e2d14c050d5ffe7e44a43d0a1b2b1f2b523502" "checksum immeta 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0b9260463a221bfe3f02100c56e2d14c050d5ffe7e44a43d0a1b2b1f2b523502"

View file

@ -10,6 +10,7 @@ path = "lib.rs"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
darling = "0.2"
quote = "0.3.15" quote = "0.3.15"
syn = { version = "0.11", features = ["visit"] } syn = { version = "0.11", features = ["visit"] }
synstructure = "0.5.2" synstructure = "0.5.2"

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use darling::FromVariant;
use quote::Tokens; use quote::Tokens;
use std::borrow::Cow; use std::borrow::Cow;
use std::iter; 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>( pub fn ref_pattern<'a>(
name: &Ident, name: &Ident,
variant: &'a Variant, variant: &'a Variant,

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[macro_use] extern crate darling;
extern crate proc_macro; extern crate proc_macro;
#[macro_use] extern crate quote; #[macro_use] extern crate quote;
extern crate syn; extern crate syn;

View file

@ -16,47 +16,8 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let style = synstructure::BindStyle::Ref.into(); let style = synstructure::BindStyle::Ref.into();
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| { let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
let mut identifier = to_css_identifier(variant.ident.as_ref()); let mut identifier = to_css_identifier(variant.ident.as_ref());
let mut css_attrs = variant.attrs.iter().filter(|attr| attr.name() == "css"); let css_attrs = cg::parse_variant_attrs::<CssAttrs>(variant);
let (is_function, use_comma) = css_attrs.next().map_or((false, false), |attr| { let separator = if css_attrs.comma { ", " } else { " " };
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 mut expr = if !bindings.is_empty() { let mut expr = if !bindings.is_empty() {
let mut expr = quote! {}; let mut expr = quote! {};
for binding in bindings { for binding in bindings {
@ -80,7 +41,7 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
::std::fmt::Write::write_str(dest, #identifier) ::std::fmt::Write::write_str(dest, #identifier)
} }
}; };
if is_function { if css_attrs.function {
identifier.push_str("("); identifier.push_str("(");
expr = quote! { expr = quote! {
::std::fmt::Write::write_str(dest, #identifier)?; ::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". /// Transforms "FooBar" to "foo-bar".
/// ///
/// If the first Camel segment is "Moz" or "Webkit", the result string /// If the first Camel segment is "Moz" or "Webkit", the result string