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

Re-export macros #170

Merged
merged 6 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 14 additions & 0 deletions strum_macros/src/helpers/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use proc_macro2::{Span, TokenStream};
use syn::{
parenthesized,
parse::{Parse, ParseStream},
parse2, parse_str,
punctuated::Punctuated,
spanned::Spanned,
Attribute, DeriveInput, Ident, LitBool, LitStr, Path, Token, Variant, Visibility,
Expand All @@ -14,6 +15,7 @@ pub mod kw {

// enum metadata
custom_keyword!(serialize_all);
custom_keyword!(crate_path);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you say serde uses "crate?" Can we also do that for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crate is a Rust keyword, is it okay if I use Crate instead?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the delay getting back to you. thanks for your patience. I would prefer crate if we can since that's what serde does. Is there a technical reason we can't do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just overcome the technical difficulties, see the latest commit, now we have

#[derive(Debug, Eq, PartialEq, EnumIter)]
#[strum(crate = "nested::module::strum")]
enum Week {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
}


// enum discriminant metadata
custom_keyword!(derive);
Expand All @@ -37,6 +39,10 @@ pub enum EnumMeta {
case_style: CaseStyle,
},
AsciiCaseInsensitive(kw::ascii_case_insensitive),
CratePath {
kw: kw::crate_path,
path: Path,
},
}

impl Parse for EnumMeta {
Expand All @@ -47,6 +53,13 @@ impl Parse for EnumMeta {
input.parse::<Token![=]>()?;
let case_style = input.parse()?;
Ok(EnumMeta::SerializeAll { kw, case_style })
} else if lookahead.peek(kw::crate_path) {
let kw = input.parse::<kw::crate_path>()?;
input.parse::<Token![=]>()?;
let path_str: LitStr = input.parse()?;
let path_tokens = parse_str(&path_str.value())?;
let path = parse2(path_tokens)?;
Ok(EnumMeta::CratePath { kw, path })
} else if lookahead.peek(kw::ascii_case_insensitive) {
let kw = input.parse()?;
Ok(EnumMeta::AsciiCaseInsensitive(kw))
Expand All @@ -61,6 +74,7 @@ impl Spanned for EnumMeta {
match self {
EnumMeta::SerializeAll { kw, .. } => kw.span(),
EnumMeta::AsciiCaseInsensitive(kw) => kw.span(),
EnumMeta::CratePath { kw, .. } => kw.span(),
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion strum_macros/src/helpers/type_props.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::TokenStream;
use quote::quote;
use std::default::Default;
use syn::{DeriveInput, Ident, Path, Visibility};
use syn::{parse_quote, DeriveInput, Ident, Path, Visibility};

use super::case_style::CaseStyle;
use super::metadata::{DeriveInputExt, EnumDiscriminantsMeta, EnumMeta};
Expand All @@ -15,6 +15,7 @@ pub trait HasTypeProperties {
pub struct StrumTypeProperties {
pub case_style: Option<CaseStyle>,
pub ascii_case_insensitive: bool,
pub crate_path: Option<Path>,
pub discriminant_derives: Vec<Path>,
pub discriminant_name: Option<Ident>,
pub discriminant_others: Vec<TokenStream>,
Expand All @@ -30,6 +31,7 @@ impl HasTypeProperties for DeriveInput {

let mut serialize_all_kw = None;
let mut ascii_case_insensitive_kw = None;
let mut crate_path_kw = None;
for meta in strum_meta {
match meta {
EnumMeta::SerializeAll { case_style, kw } => {
Expand All @@ -48,6 +50,14 @@ impl HasTypeProperties for DeriveInput {
ascii_case_insensitive_kw = Some(kw);
output.ascii_case_insensitive = true;
}
EnumMeta::CratePath { path, kw } => {
if let Some(fst_kw) = crate_path_kw {
return Err(occurrence_error(fst_kw, kw, "crate_path"));
}

crate_path_kw = Some(kw);
output.crate_path = Some(path);
}
}
}

Expand Down Expand Up @@ -83,3 +93,13 @@ impl HasTypeProperties for DeriveInput {
Ok(output)
}
}

impl StrumTypeProperties {
pub fn get_crate_path(&self) -> Path {
if let Some(path) = &self.crate_path {
parse_quote!(#path)
} else {
parse_quote!(::strum)
}
}
}
6 changes: 4 additions & 2 deletions strum_macros/src/macros/enum_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use proc_macro2::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput};

use crate::helpers::non_enum_error;
use crate::helpers::{non_enum_error, HasTypeProperties};

pub(crate) fn enum_count_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
let n = match &ast.data {
Data::Enum(v) => v.variants.len(),
_ => return Err(non_enum_error()),
};
let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();
billy1624 marked this conversation as resolved.
Show resolved Hide resolved

// Used in the quasi-quotation below as `#name`
let name = &ast.ident;
Expand All @@ -18,7 +20,7 @@ pub(crate) fn enum_count_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {

Ok(quote! {
// Implementation
impl #impl_generics ::strum::EnumCount for #name #ty_generics #where_clause {
impl #impl_generics #strum::EnumCount for #name #ty_generics #where_clause {
const COUNT: usize = #n;
}
})
Expand Down
6 changes: 4 additions & 2 deletions strum_macros/src/macros/enum_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{Data, DeriveInput, Ident};

use crate::helpers::{non_enum_error, HasStrumVariantProperties};
use crate::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties};

pub fn enum_iter_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
let name = &ast.ident;
let gen = &ast.generics;
let (impl_generics, ty_generics, where_clause) = gen.split_for_impl();
let vis = &ast.vis;
let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();
billy1624 marked this conversation as resolved.
Show resolved Hide resolved

if gen.lifetimes().count() > 0 {
return Err(syn::Error::new(
Expand Down Expand Up @@ -80,7 +82,7 @@ pub fn enum_iter_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
}
}

impl #impl_generics ::strum::IntoEnumIterator for #name #ty_generics #where_clause {
impl #impl_generics #strum::IntoEnumIterator for #name #ty_generics #where_clause {
type Iterator = #iter_name #ty_generics;
fn iter() -> #iter_name #ty_generics {
#iter_name {
Expand Down
3 changes: 2 additions & 1 deletion strum_macros/src/macros/enum_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub fn enum_message_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
};

let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();

let mut arms = Vec::new();
let mut detailed_arms = Vec::new();
Expand Down Expand Up @@ -79,7 +80,7 @@ pub fn enum_message_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
}

Ok(quote! {
impl #impl_generics ::strum::EnumMessage for #name #ty_generics #where_clause {
impl #impl_generics #strum::EnumMessage for #name #ty_generics #where_clause {
fn get_message(&self) -> ::core::option::Option<&'static str> {
match self {
#(#arms),*
Expand Down
6 changes: 4 additions & 2 deletions strum_macros/src/macros/enum_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput};

use crate::helpers::{non_enum_error, HasStrumVariantProperties};
use crate::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties};

pub fn enum_properties_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
let name = &ast.ident;
Expand All @@ -11,6 +11,8 @@ pub fn enum_properties_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
Data::Enum(v) => &v.variants,
_ => return Err(non_enum_error()),
};
let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();

let mut arms = Vec::new();
for variant in variants {
Expand Down Expand Up @@ -53,7 +55,7 @@ pub fn enum_properties_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
}

Ok(quote! {
impl #impl_generics ::strum::EnumProperty for #name #ty_generics #where_clause {
impl #impl_generics #strum::EnumProperty for #name #ty_generics #where_clause {
fn get_str(&self, prop: &str) -> ::core::option::Option<&'static str> {
match self {
#(#arms),*
Expand Down
3 changes: 2 additions & 1 deletion strum_macros/src/macros/enum_variant_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub fn enum_variant_names_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {

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

let names = variants
.iter()
Expand All @@ -26,7 +27,7 @@ pub fn enum_variant_names_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
.collect::<syn::Result<Vec<_>>>()?;

Ok(quote! {
impl #impl_generics ::strum::VariantNames for #name #ty_generics #where_clause {
impl #impl_generics #strum::VariantNames for #name #ty_generics #where_clause {
const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
}
})
Expand Down
4 changes: 3 additions & 1 deletion strum_macros/src/macros/strings/as_ref_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub fn as_static_str_inner(
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let arms = get_arms(ast)?;
let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();

let mut generics = ast.generics.clone();
generics
Expand All @@ -88,7 +90,7 @@ pub fn as_static_str_inner(

Ok(match trait_variant {
GenerateTraitVariant::AsStaticStr => quote! {
impl #impl_generics ::strum::AsStaticRef<str> for #name #ty_generics #where_clause {
impl #impl_generics #strum::AsStaticRef<str> for #name #ty_generics #where_clause {
fn as_static(&self) -> &'static str {
match *self {
#(#arms),*
Expand Down
5 changes: 3 additions & 2 deletions strum_macros/src/macros/strings/from_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ pub fn from_string_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
};

let type_properties = ast.get_type_properties()?;
let strum = type_properties.get_crate_path();

let mut default_kw = None;
let mut default =
quote! { _ => ::std::result::Result::Err(::strum::ParseError::VariantNotFound) };
quote! { _ => ::std::result::Result::Err(#strum::ParseError::VariantNotFound) };
let mut arms = Vec::new();
for variant in variants {
let ident = &variant.ident;
Expand Down Expand Up @@ -89,7 +90,7 @@ pub fn from_string_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
Ok(quote! {
#[allow(clippy::use_self)]
impl #impl_generics ::std::str::FromStr for #name #ty_generics #where_clause {
type Err = ::strum::ParseError;
type Err = #strum::ParseError;
fn from_str(s: &str) -> ::std::result::Result< #name #ty_generics , Self::Err> {
match s {
#(#arms),*
Expand Down