mirror of
https://github.com/danog/strum.git
synced 2024-11-30 04:28:59 +01:00
* Adding vis to EnumDiscriminants (#137) * Improved doctest example names (#137) * Fixing incorrect occurrence_error attr string * Using r#pub on doctest * Adding tests for discriminant visibility, and rustc-cfg for bare "pub" * Doing local import with "self::" * Back to having tests pass on latest stable * Moved sample doctest with vis example to separate nocompile block
This commit is contained in:
parent
90047fee86
commit
ddb9c2682e
@ -4,7 +4,7 @@ use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
Attribute, DeriveInput, Ident, LitStr, Path, Token, Variant,
|
||||
Attribute, DeriveInput, Ident, LitStr, Path, Token, Variant, Visibility,
|
||||
};
|
||||
|
||||
use super::case_style::CaseStyle;
|
||||
@ -18,6 +18,7 @@ pub mod kw {
|
||||
// enum discriminant metadata
|
||||
custom_keyword!(derive);
|
||||
custom_keyword!(name);
|
||||
custom_keyword!(vis);
|
||||
|
||||
// variant metadata
|
||||
custom_keyword!(message);
|
||||
@ -56,6 +57,7 @@ impl Spanned for EnumMeta {
|
||||
pub enum EnumDiscriminantsMeta {
|
||||
Derive { kw: kw::derive, paths: Vec<Path> },
|
||||
Name { kw: kw::name, name: Ident },
|
||||
Vis { kw: kw::vis, vis: Visibility },
|
||||
Other { path: Path, nested: TokenStream },
|
||||
}
|
||||
|
||||
@ -76,6 +78,12 @@ impl Parse for EnumDiscriminantsMeta {
|
||||
parenthesized!(content in input);
|
||||
let name = content.parse()?;
|
||||
Ok(EnumDiscriminantsMeta::Name { kw, name })
|
||||
} else if input.peek(kw::vis) {
|
||||
let kw = input.parse()?;
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
let vis = content.parse()?;
|
||||
Ok(EnumDiscriminantsMeta::Vis { kw, vis })
|
||||
} else {
|
||||
let path = input.parse()?;
|
||||
let content;
|
||||
@ -91,6 +99,7 @@ impl Spanned for EnumDiscriminantsMeta {
|
||||
match self {
|
||||
EnumDiscriminantsMeta::Derive { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Name { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Vis { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Other { path, .. } => path.span(),
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::default::Default;
|
||||
use syn::{DeriveInput, Ident, Path};
|
||||
use syn::{DeriveInput, Ident, Path, Visibility};
|
||||
|
||||
use super::case_style::CaseStyle;
|
||||
use super::metadata::{DeriveInputExt, EnumDiscriminantsMeta, EnumMeta};
|
||||
@ -17,6 +17,7 @@ pub struct StrumTypeProperties {
|
||||
pub discriminant_derives: Vec<Path>,
|
||||
pub discriminant_name: Option<Ident>,
|
||||
pub discriminant_others: Vec<TokenStream>,
|
||||
pub discriminant_vis: Option<Visibility>,
|
||||
}
|
||||
|
||||
impl HasTypeProperties for DeriveInput {
|
||||
@ -41,6 +42,7 @@ impl HasTypeProperties for DeriveInput {
|
||||
}
|
||||
|
||||
let mut name_kw = None;
|
||||
let mut vis_kw = None;
|
||||
for meta in discriminants_meta {
|
||||
match meta {
|
||||
EnumDiscriminantsMeta::Derive { paths, .. } => {
|
||||
@ -54,6 +56,14 @@ impl HasTypeProperties for DeriveInput {
|
||||
name_kw = Some(kw);
|
||||
output.discriminant_name = Some(name);
|
||||
}
|
||||
EnumDiscriminantsMeta::Vis { vis, kw } => {
|
||||
if let Some(fst_kw) = vis_kw {
|
||||
return Err(occurrence_error(fst_kw, kw, "vis"));
|
||||
}
|
||||
|
||||
vis_kw = Some(kw);
|
||||
output.discriminant_vis = Some(vis);
|
||||
}
|
||||
EnumDiscriminantsMeta::Other { path, nested } => {
|
||||
output.discriminant_others.push(quote! { #path(#nested) });
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ pub fn enum_properties(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
/// Variant1 { a: NonDefault },
|
||||
/// }
|
||||
///
|
||||
/// // You can also rename the generated enum using the `#[strum_discriminants(name(OtherName))]` attribute:
|
||||
/// // You can rename the generated enum using the `#[strum_discriminants(name(OtherName))]` attribute:
|
||||
/// # #[allow(dead_code)]
|
||||
/// #[derive(Debug, EnumDiscriminants)]
|
||||
/// #[strum_discriminants(derive(EnumIter))]
|
||||
@ -607,6 +607,34 @@ pub fn enum_properties(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
/// MyVariants::iter().collect::<Vec<_>>()
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// It is also possible to specify the visibility (e.g. `pub`/`pub(crate)`/etc.)
|
||||
/// of the generated enum. By default, the generated enum inherits the
|
||||
/// visibility of the parent enum it was generated from.
|
||||
///
|
||||
/// ```nocompile
|
||||
/// use strum_macros::EnumDiscriminants;
|
||||
///
|
||||
/// // You can set the visibility of the generated enum using the `#[strum_discriminants(vis(..))]` attribute:
|
||||
/// mod inner {
|
||||
/// use strum_macros::EnumDiscriminants;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// #[derive(Debug, EnumDiscriminants)]
|
||||
/// #[strum_discriminants(vis(pub))]
|
||||
/// #[strum_discriminants(name(PubDiscriminants))]
|
||||
/// enum PrivateEnum {
|
||||
/// Variant0(bool),
|
||||
/// Variant1 { a: bool },
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // test visibility example, `PrivateEnum` should not be accessible here
|
||||
/// assert_ne!(
|
||||
/// inner::PubDiscriminants::Variant0,
|
||||
/// inner::PubDiscriminants::Variant1,
|
||||
/// );
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enumdiscriminants-name",
|
||||
proc_macro_derive(StrumEnumDiscriminants, attributes(strum, strum_discriminants))
|
||||
|
@ -36,6 +36,7 @@ pub fn enum_discriminants_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
);
|
||||
|
||||
let discriminants_name = type_properties.discriminant_name.unwrap_or(default_name);
|
||||
let discriminants_vis = type_properties.discriminant_vis.unwrap_or_else(|| vis.clone());
|
||||
|
||||
// Pass through all other attributes
|
||||
let pass_though_attributes = type_properties.discriminant_others;
|
||||
@ -127,7 +128,7 @@ pub fn enum_discriminants_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
/// Auto-generated discriminant enum variants
|
||||
#derives
|
||||
#(#[ #pass_though_attributes ])*
|
||||
#vis enum #discriminants_name {
|
||||
#discriminants_vis enum #discriminants_name {
|
||||
#(#discriminants),*
|
||||
}
|
||||
|
||||
|
@ -2,5 +2,6 @@ fn main() {
|
||||
// Check if version of rustc is >= 1.34
|
||||
if let Some(true) = version_check::is_min_version("1.34.0") {
|
||||
println!("cargo:rustc-cfg=try_from");
|
||||
println!("cargo:rustc-cfg=bare_pub");
|
||||
}
|
||||
}
|
||||
|
@ -215,3 +215,45 @@ fn filter_variant_attributes_pass_through() {
|
||||
VariantFilterAttrDiscs::from_str("dark_black").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(bare_pub)]
|
||||
#[test]
|
||||
fn override_visibility() {
|
||||
mod private {
|
||||
use super::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(EnumDiscriminants)]
|
||||
#[strum_discriminants(name(PubDiscriminants), vis(pub))]
|
||||
enum PrivateEnum {
|
||||
VariantA(bool),
|
||||
VariantB(bool),
|
||||
}
|
||||
}
|
||||
|
||||
assert_ne!(
|
||||
private::PubDiscriminants::VariantA,
|
||||
private::PubDiscriminants::VariantB,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(bare_pub))]
|
||||
#[test]
|
||||
fn override_visibility() {
|
||||
mod private {
|
||||
use super::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(EnumDiscriminants)]
|
||||
#[strum_discriminants(name(PubDiscriminants), vis(r#pub))]
|
||||
enum PrivateEnum {
|
||||
VariantA(bool),
|
||||
VariantB(bool),
|
||||
}
|
||||
}
|
||||
|
||||
assert_ne!(
|
||||
private::PubDiscriminants::VariantA,
|
||||
private::PubDiscriminants::VariantB,
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user