Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/73/whitelist variant attributes to copy #82

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

* Only copy across `"doc", "cfg", "allow", "deny"` attributes from main enum variants to discriminant variants. [#73](https://github.com/Peternator7/strum/issues/73)

## 0.17.1

* Fixed an issue caused by combining [#60](https://github.com/Peternator7/strum/pull/60) and [#76](https://github.com/Peternator7/strum/pull/76)
Expand Down
12 changes: 9 additions & 3 deletions strum_macros/src/macros/enum_discriminants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use syn;

use helpers::extract_meta;

/// Attributes to copy from the main enum's variants to the discriminant enum's variants.
///
/// Attributes not in this list may be for other `proc_macro`s on the main enum, and may cause
/// compilation problems when copied across.
const ATTRIBUTES_TO_COPY: &[&str] = &["doc", "cfg", "allow", "deny"];

pub fn enum_discriminants_inner(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let vis = &ast.vis;
Expand Down Expand Up @@ -66,9 +72,9 @@ pub fn enum_discriminants_inner(ast: &syn::DeriveInput) -> TokenStream {

// Don't copy across the "strum" meta attribute.
let attrs = variant.attrs.iter().filter(|attr| {
attr.parse_meta()
.map(|meta| !meta.path().is_ident("strum"))
.unwrap_or(true)
ATTRIBUTES_TO_COPY
.iter()
.any(|attr_whitelisted| attr.path.is_ident(attr_whitelisted))
});

discriminants.push(quote! { #(#attrs)* #ident });
Expand Down
1 change: 1 addition & 0 deletions strum_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ authors = ["Peter Glotfelty <peglotfe@microsoft.com>"]
strum = { path = "../strum", features = ["derive"] }
strum_macros = { path = "../strum_macros", features = [] }
clap = "2.33.0"
enum_variant_type = "0.2.0"
structopt = "0.2.18"
34 changes: 34 additions & 0 deletions strum_tests/tests/enum_discriminants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
extern crate strum;
#[macro_use]
extern crate strum_macros;
#[macro_use]
extern crate enum_variant_type;

use strum::IntoEnumIterator;

Expand Down Expand Up @@ -184,3 +186,35 @@ fn from_ref_test_complex() {
let rara = Rara;
assert_eq!(EnumIntoComplexVars::A, (&EnumIntoComplex::A(&rara)).into());
}

#[allow(dead_code)]
#[derive(Debug, Eq, PartialEq, EnumDiscriminants, EnumVariantType)]
#[strum_discriminants(
name(VariantFilterAttrDiscs),
derive(Display, EnumIter, EnumString),
strum(serialize_all = "snake_case")
)]
enum VariantFilterAttr {
#[evt(derive(Clone, Copy, Debug))]
DarkBlack(bool),
#[evt(skip)]
BrightWhite(i32),
}

#[test]
fn filter_variant_attributes_pass_through() {
use std::str::FromStr;

let discriminants = VariantFilterAttrDiscs::iter().collect::<Vec<_>>();
let expected = vec![
VariantFilterAttrDiscs::DarkBlack,
VariantFilterAttrDiscs::BrightWhite,
];

assert_eq!(expected, discriminants);
assert_eq!("dark_black", VariantFilterAttrDiscs::DarkBlack.to_string());
assert_eq!(
VariantFilterAttrDiscs::DarkBlack,
VariantFilterAttrDiscs::from_str("dark_black").unwrap()
);
}