Skip to content
Draft
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
15 changes: 13 additions & 2 deletions strum_macros/src/helpers/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use syn::{
parse::{Parse, ParseStream},
parse2, parse_str,
punctuated::Punctuated,
Attribute, DeriveInput, Expr, ExprLit, Field, Ident, Lit, LitBool, LitStr, Meta, MetaNameValue,
Path, Token, Variant, Visibility,
Attribute, DeriveInput, Expr, ExprLit, Field, Ident, Lit, LitBool, LitStr, Meta, MetaList,
MetaNameValue, Path, Token, Variant, Visibility,
};

use super::case_style::CaseStyle;
Expand All @@ -27,6 +27,7 @@ pub mod kw {
custom_keyword!(name);
custom_keyword!(vis);
custom_keyword!(doc);
custom_keyword!(attributes);

// variant metadata
custom_keyword!(message);
Expand Down Expand Up @@ -125,6 +126,7 @@ pub enum EnumDiscriminantsMeta {
Derive { _kw: kw::derive, paths: Vec<Path> },
Name { kw: kw::name, name: Ident },
Vis { kw: kw::vis, vis: Visibility },
Attributes { _kw: kw::attributes, attributes: Vec<MetaList> },
Other { passthrough_meta: Meta },
}

Expand All @@ -151,6 +153,15 @@ impl Parse for EnumDiscriminantsMeta {
parenthesized!(content in input);
let vis = content.parse()?;
Ok(EnumDiscriminantsMeta::Vis { kw, vis })
} else if input.peek(kw::attributes) {
let _kw = input.parse()?;
let content;
parenthesized!(content in input);
let attributes = content.parse_terminated(MetaList::parse, Token![,])?;
Ok(EnumDiscriminantsMeta::Attributes {
_kw,
attributes: attributes.into_iter().collect(),
})
} else {
let passthrough_meta = input.parse()?;
Ok(EnumDiscriminantsMeta::Other { passthrough_meta })
Expand Down
6 changes: 5 additions & 1 deletion strum_macros/src/helpers/type_props.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use proc_macro2::TokenStream;
use std::default::Default;
use syn::{parse_quote, DeriveInput, Ident, LitStr, Meta, Path, Visibility};
use syn::{parse_quote, DeriveInput, Ident, LitStr, Meta, MetaList, Path, Visibility};

use super::case_style::CaseStyle;
use super::metadata::{DeriveInputExt, EnumDiscriminantsMeta, EnumMeta};
Expand All @@ -21,6 +21,7 @@ pub struct StrumTypeProperties {
pub discriminant_name: Option<Ident>,
pub discriminant_others: Vec<Meta>,
pub discriminant_vis: Option<Visibility>,
pub discriminant_attributes: Vec<MetaList>,
pub use_phf: bool,
pub prefix: Option<LitStr>,
pub suffix: Option<LitStr>,
Expand Down Expand Up @@ -148,6 +149,9 @@ impl HasTypeProperties for DeriveInput {
vis_kw = Some(kw);
output.discriminant_vis = Some(vis);
}
EnumDiscriminantsMeta::Attributes { attributes, .. } => {
output.discriminant_attributes.extend(attributes);
}
EnumDiscriminantsMeta::Other { passthrough_meta } => {
output.discriminant_others.push(passthrough_meta);
}
Expand Down
20 changes: 18 additions & 2 deletions strum_macros/src/macros/enum_discriminants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use proc_macro2::{Span, TokenStream, TokenTree};
use quote::{quote, ToTokens};
use syn::parse_quote;
use syn::{parse_quote, MetaList};
use syn::{Data, DeriveInput, Fields};

use crate::helpers::{non_enum_error, strum_discriminants_passthrough_error, HasTypeProperties};
Expand All @@ -20,8 +20,23 @@ pub fn enum_discriminants_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
_ => return Err(non_enum_error()),
};

// Derives for the generated enum
let type_properties = ast.get_type_properties()?;

// Attributes for the generated enum
let attributes: &Vec<MetaList> = &type_properties.discriminant_attributes;

let attributes: Vec<_> = attributes
.iter()
.map(|a| {
quote! {
#[#a]
}
})
.collect();

let attributes = quote! {#(#attributes)*};

// Derives for the generated enum
let strum_module_path = type_properties.crate_module_path();

let mut derives = type_properties.discriminant_derives;
Expand Down Expand Up @@ -223,6 +238,7 @@ pub fn enum_discriminants_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
};

Ok(quote! {
#attributes
#derives
#repr
#(#[ #pass_through_attributes ])*
Expand Down