Skip to content

Commit

Permalink
Bump dependencies (mainly syn crate) (Peternator7#22)
Browse files Browse the repository at this point in the history
* Bump dependencies

* Cache intepreted meta to reduce memory allocation
  • Loading branch information
lo48576 authored and Peternator7 committed May 12, 2018
1 parent ae40df1 commit 179e8ea
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 205 deletions.
4 changes: 2 additions & 2 deletions strum_macros/Cargo.toml
Expand Up @@ -17,5 +17,5 @@ proc-macro = true
name = "strum_macros"

[dependencies]
quote = "0.3.12"
syn = "0.11.4"
quote = "0.5.2"
syn = { version = "0.13.7", features = ["parsing"] }
29 changes: 15 additions & 14 deletions strum_macros/src/as_ref_str.rs
Expand Up @@ -2,45 +2,46 @@
use quote;
use syn;

use helpers::{unique_attr, extract_attrs, is_disabled};
use helpers::{unique_attr, extract_attrs, extract_meta, is_disabled};

pub fn as_ref_str_inner(ast: &syn::DeriveInput) -> quote::Tokens {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let variants = match ast.body {
syn::Body::Enum(ref v) => v,
let variants = match ast.data {
syn::Data::Enum(ref v) => &v.variants,
_ => panic!("AsRefStr only works on Enums"),
};

let mut arms = Vec::new();
for variant in variants {
use syn::VariantData::*;
use syn::Fields::*;
let ident = &variant.ident;
let meta = extract_meta(&variant.attrs);

if is_disabled(&variant.attrs) {
if is_disabled(&meta) {
continue;
}

// Look at all the serialize attributes.
// Use `to_string` attribute (not `as_ref_str` or something) to keep things consistent
// (i.e. always `enum.as_ref().to_string() == enum.to_string()`).
let output = if let Some(n) = unique_attr(&variant.attrs, "strum", "to_string") {
let output = if let Some(n) = unique_attr(&meta, "strum", "to_string") {
n
} else {
let mut attrs = extract_attrs(&variant.attrs, "strum", "serialize");
let mut attrs = extract_attrs(&meta, "strum", "serialize");
// We always take the longest one. This is arbitary, but is *mostly* deterministic
attrs.sort_by_key(|s| -(s.len() as isize));
if let Some(n) = attrs.first() {
attrs.sort_by_key(|s| s.len());
if let Some(n) = attrs.pop() {
n
} else {
ident.as_ref()
ident.to_string()
}
};

let params = match variant.data {
Unit => quote::Ident::from(""),
Tuple(..) => quote::Ident::from("(..)"),
Struct(..) => quote::Ident::from("{..}"),
let params = match variant.fields {
Unit => quote!{},
Unnamed(..) => quote!{ (..) },
Named(..) => quote!{ {..} },
};

arms.push(quote!{ #name::#ident #params => #output });
Expand Down
29 changes: 15 additions & 14 deletions strum_macros/src/display.rs
Expand Up @@ -2,43 +2,44 @@
use quote;
use syn;

use helpers::{unique_attr, extract_attrs, is_disabled};
use helpers::{unique_attr, extract_attrs, extract_meta, is_disabled};

pub fn display_inner(ast: &syn::DeriveInput) -> quote::Tokens {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let variants = match ast.body {
syn::Body::Enum(ref v) => v,
let variants = match ast.data {
syn::Data::Enum(ref v) => &v.variants,
_ => panic!("Display only works on Enums"),
};

let mut arms = Vec::new();
for variant in variants {
use syn::VariantData::*;
use syn::Fields::*;
let ident = &variant.ident;
let meta = extract_meta(&variant.attrs);

if is_disabled(&variant.attrs) {
if is_disabled(&meta) {
continue;
}

// Look at all the serialize attributes.
let output = if let Some(n) = unique_attr(&variant.attrs, "strum", "to_string") {
let output = if let Some(n) = unique_attr(&meta, "strum", "to_string") {
n
} else {
let mut attrs = extract_attrs(&variant.attrs, "strum", "serialize");
let mut attrs = extract_attrs(&meta, "strum", "serialize");
// We always take the longest one. This is arbitary, but is *mostly* deterministic
attrs.sort_by_key(|s| -(s.len() as isize));
if let Some(n) = attrs.first() {
attrs.sort_by_key(|s| s.len());
if let Some(n) = attrs.pop() {
n
} else {
ident.as_ref()
ident.to_string()
}
};

let params = match variant.data {
Unit => quote::Ident::from(""),
Tuple(..) => quote::Ident::from("(..)"),
Struct(..) => quote::Ident::from("{..}"),
let params = match variant.fields {
Unit => quote!{},
Unnamed(..) => quote!{ (..) },
Named(..) => quote!{ {..} },
};

arms.push(quote!{ #name::#ident #params => f.write_str(#output) });
Expand Down
58 changes: 21 additions & 37 deletions strum_macros/src/enum_iter.rs
@@ -1,65 +1,49 @@
use quote;
use syn;

use helpers::is_disabled;
use helpers::{extract_meta, is_disabled};

pub fn enum_iter_inner(ast: &syn::DeriveInput) -> quote::Tokens {
let name = &ast.ident;
let gen = &ast.generics;
let (impl_generics, ty_generics, where_clause) = gen.split_for_impl();
let vis = &ast.vis;

if gen.lifetimes.len() > 0 {
if gen.lifetimes().count() > 0 {
panic!("Enum Iterator isn't supported on Enums with lifetimes. The resulting enums would \
be unbounded.");
}

let phantom_data = if gen.ty_params.len() > 0 {
let g = gen.ty_params
.iter()
.map(|param| &param.ident)
.collect::<Vec<_>>();
quote!{ < ( #(#g),* ) > }
let phantom_data = if gen.type_params().count() > 0 {
let g = gen.type_params().map(|param| &param.ident);
quote! { < ( #(#g),* ) > }
} else {
quote! { < () > }
};

let variants = match ast.body {
syn::Body::Enum(ref v) => v,
let variants = match ast.data {
syn::Data::Enum(ref v) => &v.variants,
_ => panic!("EnumIter only works on Enums"),
};

let mut arms = Vec::new();
let enabled = variants
.iter()
.filter(|variant| !is_disabled(&variant.attrs));
.filter(|variant| !is_disabled(&extract_meta(&variant.attrs)));

for (idx, variant) in enabled.enumerate() {
use syn::VariantData::*;
use syn::Fields::*;
let ident = &variant.ident;
let params = match variant.data {
Unit => quote::Ident::from(""),
Tuple(ref fields) => {
let default = fields
.iter()
.map(|_| "::std::default::Default::default()")
.collect::<Vec<_>>()
.join(", ");

quote::Ident::from(&*format!("({})", default))
let params = match variant.fields {
Unit => quote!{},
Unnamed(ref fields) => {
let defaults = ::std::iter::repeat(quote!(::std::default::Default::default()))
.take(fields.unnamed.len());
quote! { (#(#defaults),*) }
}
Struct(ref fields) => {
let default = fields
.iter()
.map(|field| {
format!("{}: {}",
field.ident.as_ref().unwrap(),
"::std::default::Default::default()")
})
.collect::<Vec<_>>()
.join(", ");

quote::Ident::from(&*format!("{{{}}}", default))
Named(ref fields) => {
let fields = fields.named.iter().map(|field| field.ident.unwrap());
quote! { {#(#fields: ::std::default::Default::default()),*} }
}
};

Expand All @@ -68,7 +52,7 @@ pub fn enum_iter_inner(ast: &syn::DeriveInput) -> quote::Tokens {

let variant_count = arms.len();
arms.push(quote! { _ => ::std::option::Option::None });
let iter_name = quote::Ident::from(&*format!("{}Iter", name));
let iter_name = syn::parse_str::<syn::Ident>(&format!("{}Iter", name)).unwrap();
quote!{
#vis struct #iter_name #ty_generics {
idx: usize,
Expand All @@ -84,10 +68,10 @@ pub fn enum_iter_inner(ast: &syn::DeriveInput) -> quote::Tokens {
}
}
}

impl #impl_generics Iterator for #iter_name #ty_generics #where_clause {
type Item = #name #ty_generics;

fn next(&mut self) -> Option<#name #ty_generics> {
let output = match self.idx {
#(#arms),*
Expand Down
27 changes: 14 additions & 13 deletions strum_macros/src/enum_messages.rs
@@ -1,13 +1,13 @@
use quote;
use syn;

use helpers::{unique_attr, extract_attrs, is_disabled};
use helpers::{unique_attr, extract_attrs, extract_meta, is_disabled};

pub fn enum_message_inner(ast: &syn::DeriveInput) -> quote::Tokens {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let variants = match ast.body {
syn::Body::Enum(ref v) => v,
let variants = match ast.data {
syn::Data::Enum(ref v) => &v.variants,
_ => panic!("EnumMessage only works on Enums"),
};

Expand All @@ -16,22 +16,23 @@ pub fn enum_message_inner(ast: &syn::DeriveInput) -> quote::Tokens {
let mut serializations = Vec::new();

for variant in variants {
let messages = unique_attr(&variant.attrs, "strum", "message");
let detailed_messages = unique_attr(&variant.attrs, "strum", "detailed_message");
let meta = extract_meta(&variant.attrs);
let messages = unique_attr(&meta, "strum", "message");
let detailed_messages = unique_attr(&meta, "strum", "detailed_message");
let ident = &variant.ident;

use syn::VariantData::*;
let params = match variant.data {
Unit => quote::Ident::from(""),
Tuple(..) => quote::Ident::from("(..)"),
Struct(..) => quote::Ident::from("{..}"),
use syn::Fields::*;
let params = match variant.fields {
Unit => quote!{},
Unnamed(..) => quote!{ (..) },
Named(..) => quote!{ {..} },
};

// You can't disable getting the serializations.
{
let mut serialization_variants = extract_attrs(&variant.attrs, "strum", "serialize");
let mut serialization_variants = extract_attrs(&meta, "strum", "serialize");
if serialization_variants.len() == 0 {
serialization_variants.push(ident.as_ref());
serialization_variants.push(ident.to_string());
}

let count = serialization_variants.len();
Expand All @@ -44,7 +45,7 @@ pub fn enum_message_inner(ast: &syn::DeriveInput) -> quote::Tokens {
}

// But you can disable the messages.
if is_disabled(&variant.attrs) {
if is_disabled(&meta) {
continue;
}

Expand Down

0 comments on commit 179e8ea

Please sign in to comment.