mirror of
https://github.com/danog/strum.git
synced 2024-11-26 20:14:40 +01:00
Did additional refactoring and added helpful trait methods to improve readability
This commit is contained in:
parent
8502a1cabc
commit
ca17ae7581
@ -1,4 +1,6 @@
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase, TitleCase};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum CaseStyle {
|
||||
CamelCase,
|
||||
KebabCase,
|
||||
@ -43,3 +45,45 @@ impl<'s> From<&'s str> for CaseStyle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CaseStyleHelpers {
|
||||
fn convert_case(&self, case_style: Option<CaseStyle>) -> String;
|
||||
}
|
||||
|
||||
impl CaseStyleHelpers for syn::Ident {
|
||||
fn convert_case(&self, case_style: Option<CaseStyle>) -> String {
|
||||
let ident_string = self.to_string();
|
||||
if let Some(case_style) = case_style {
|
||||
match case_style {
|
||||
CaseStyle::PascalCase => ident_string.to_camel_case(),
|
||||
CaseStyle::KebabCase => ident_string.to_kebab_case(),
|
||||
CaseStyle::MixedCase => ident_string.to_mixed_case(),
|
||||
CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),
|
||||
CaseStyle::SnakeCase => ident_string.to_snake_case(),
|
||||
CaseStyle::TitleCase => ident_string.to_title_case(),
|
||||
CaseStyle::UpperCase => ident_string.to_uppercase(),
|
||||
CaseStyle::LowerCase => ident_string.to_lowercase(),
|
||||
CaseStyle::ScreamingKebabCase => ident_string.to_kebab_case().to_uppercase(),
|
||||
CaseStyle::CamelCase => {
|
||||
let camel_case = ident_string.to_camel_case();
|
||||
let mut pascal = String::with_capacity(camel_case.len());
|
||||
let mut it = camel_case.chars();
|
||||
if let Some(ch) = it.next() {
|
||||
pascal.extend(ch.to_lowercase());
|
||||
}
|
||||
pascal.extend(it);
|
||||
pascal
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ident_string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_case() {
|
||||
let id = syn::Ident::new("test_me", proc_macro2::Span::call_site());
|
||||
assert_eq!("testMe", id.convert_case(Some(CaseStyle::CamelCase)));
|
||||
assert_eq!("TestMe", id.convert_case(Some(CaseStyle::PascalCase)));
|
||||
}
|
@ -1,18 +1,15 @@
|
||||
use syn::{Meta, MetaList};
|
||||
|
||||
use syn::Meta;
|
||||
use super::MetaHelpers;
|
||||
use super::MetaListHelpers;
|
||||
|
||||
pub trait MetaIteratorHelpers {
|
||||
type Item;
|
||||
|
||||
fn unique_meta_list(self, attr: &str) -> Option<Self::Item>;
|
||||
fn extract_attrs(self, attr: &str, prop: &str) -> Vec<String>;
|
||||
fn find_attribute(&self, attr: &str) -> std::vec::IntoIter<&Meta>;
|
||||
fn find_properties(&self, attr: &str, prop: &str) -> Vec<String>;
|
||||
|
||||
fn unique_attr(self, attr: &str, prop: &str) -> Option<String>
|
||||
where Self: Sized
|
||||
fn find_unique_property(&self, attr: &str, prop: &str) -> Option<String>
|
||||
{
|
||||
let mut curr = self.extract_attrs(attr, prop);
|
||||
let mut curr = self.find_properties(attr, prop);
|
||||
if curr.len() > 1 {
|
||||
panic!("More than one property: {} found on variant", prop);
|
||||
}
|
||||
@ -20,10 +17,9 @@ pub trait MetaIteratorHelpers {
|
||||
curr.pop()
|
||||
}
|
||||
|
||||
fn is_disabled(self) -> bool
|
||||
where Self: Sized
|
||||
fn is_disabled(&self) -> bool
|
||||
{
|
||||
let v = self.extract_attrs("strum", "disabled");
|
||||
let v = self.find_properties("strum", "disabled");
|
||||
match v.len() {
|
||||
0 => false,
|
||||
1 => v[0] == "true",
|
||||
@ -32,44 +28,29 @@ pub trait MetaIteratorHelpers {
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a, I> MetaIteratorHelpers for I
|
||||
//impl MetaIteratorHelpers for [Meta]
|
||||
impl <T> MetaIteratorHelpers for [T]
|
||||
where
|
||||
I: std::iter::IntoIterator<Item=&'a Meta>
|
||||
T: std::borrow::Borrow<Meta>
|
||||
{
|
||||
type Item=&'a MetaList;
|
||||
|
||||
/// Returns the `MetaList` that matches the given name from the list of `Meta`s, or `None`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if more than one `Meta` exists with the name.
|
||||
fn unique_meta_list(self, attr: &str) -> Option<&'a MetaList>
|
||||
where
|
||||
Self: Sized
|
||||
{
|
||||
// let mut curr = get_meta_list(metas.into_iter(), attr).collect::<Vec<_>>();
|
||||
let mut curr = self.into_iter()
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
.filter(|list| list.path.is_ident(attr))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if curr.len() > 1 {
|
||||
panic!("More than one `{}` attribute found on type", attr);
|
||||
}
|
||||
|
||||
curr.pop()
|
||||
}
|
||||
|
||||
fn extract_attrs(self, attr: &str, prop: &str) -> Vec<String>
|
||||
where
|
||||
Self: Sized
|
||||
{
|
||||
use syn::{Lit, MetaNameValue};
|
||||
self.into_iter()
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
fn find_attribute(&self, attr: &str) -> std::vec::IntoIter<&Meta> {
|
||||
self.iter()
|
||||
.filter_map(|meta| meta.borrow().try_metalist())
|
||||
.filter(|list| list.path.is_ident(attr))
|
||||
.flat_map(|list| list.expand_inner())
|
||||
// Get all the inner elements as long as they start with ser.
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
fn find_properties(&self, attr: &str, prop: &str) -> Vec<String>
|
||||
{
|
||||
use syn::{Lit, MetaNameValue};
|
||||
self.iter()
|
||||
// Only look at MetaList style attributes `[strum(...)]`
|
||||
.filter_map(|meta| meta.borrow().try_metalist())
|
||||
.filter(|list| list.path.is_ident(attr))
|
||||
.flat_map(|list| list.expand_inner())
|
||||
// Match all the properties with a given ident `[strum(serialize = "value")]`
|
||||
.filter_map(|meta| match *meta {
|
||||
Meta::NameValue(MetaNameValue {
|
||||
ref path,
|
||||
|
@ -1,6 +1,5 @@
|
||||
use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase, TitleCase};
|
||||
use syn::{Attribute, Ident, Meta, MetaList};
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
|
||||
use syn::{Attribute, Meta};
|
||||
|
||||
pub mod case_style;
|
||||
mod metalist_helpers;
|
||||
@ -10,6 +9,7 @@ mod meta_iterator_helpers;
|
||||
pub use self::metalist_helpers::MetaListHelpers;
|
||||
pub use self::meta_helpers::MetaHelpers;
|
||||
pub use self::meta_iterator_helpers::MetaIteratorHelpers;
|
||||
pub use self::case_style::CaseStyleHelpers;
|
||||
|
||||
pub fn extract_meta(attrs: &[Attribute]) -> Vec<Meta> {
|
||||
attrs
|
||||
@ -17,61 +17,3 @@ pub fn extract_meta(attrs: &[Attribute]) -> Vec<Meta> {
|
||||
.filter_map(|attribute| attribute.parse_meta().ok())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns the `MetaList` that matches the given name from the list of `Meta`s, or `None`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if more than one `Meta` exists with the name.
|
||||
pub fn unique_meta_list<'meta, MetaIt>(metas: MetaIt, attr: &'meta str) -> Option<&'meta MetaList>
|
||||
where
|
||||
MetaIt: Iterator<Item = &'meta Meta>,
|
||||
{
|
||||
// let mut curr = get_meta_list(metas.into_iter(), attr).collect::<Vec<_>>();
|
||||
let mut curr = metas
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
.filter(|list| list.path.is_ident(attr))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if curr.len() > 1 {
|
||||
panic!("More than one `{}` attribute found on type", attr);
|
||||
}
|
||||
|
||||
curr.pop()
|
||||
}
|
||||
|
||||
pub fn convert_case(ident: &Ident, case_style: Option<CaseStyle>) -> String {
|
||||
let ident_string = ident.to_string();
|
||||
if let Some(case_style) = case_style {
|
||||
match case_style {
|
||||
CaseStyle::PascalCase => ident_string.to_camel_case(),
|
||||
CaseStyle::KebabCase => ident_string.to_kebab_case(),
|
||||
CaseStyle::MixedCase => ident_string.to_mixed_case(),
|
||||
CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),
|
||||
CaseStyle::SnakeCase => ident_string.to_snake_case(),
|
||||
CaseStyle::TitleCase => ident_string.to_title_case(),
|
||||
CaseStyle::UpperCase => ident_string.to_uppercase(),
|
||||
CaseStyle::LowerCase => ident_string.to_lowercase(),
|
||||
CaseStyle::ScreamingKebabCase => ident_string.to_kebab_case().to_uppercase(),
|
||||
CaseStyle::CamelCase => {
|
||||
let camel_case = ident_string.to_camel_case();
|
||||
let mut pascal = String::with_capacity(camel_case.len());
|
||||
let mut it = camel_case.chars();
|
||||
if let Some(ch) = it.next() {
|
||||
pascal.extend(ch.to_lowercase());
|
||||
}
|
||||
pascal.extend(it);
|
||||
pascal
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ident_string
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_case() {
|
||||
let id = Ident::new("test_me", proc_macro2::Span::call_site());
|
||||
assert_eq!("testMe", convert_case(&id, Some(CaseStyle::CamelCase)));
|
||||
assert_eq!("TestMe", convert_case(&id, Some(CaseStyle::PascalCase)));
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::helpers::{MetaHelpers, MetaListHelpers};
|
||||
use crate::helpers::{MetaHelpers, MetaListHelpers, MetaIteratorHelpers};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use syn;
|
||||
|
||||
use helpers::{extract_meta, unique_meta_list};
|
||||
use helpers::{extract_meta};
|
||||
|
||||
pub fn enum_discriminants_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
@ -15,19 +15,12 @@ pub fn enum_discriminants_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
// Derives for the generated enum
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let discriminant_attrs = type_meta.iter()
|
||||
// We are only looking at 'metalist' style attributes [list(item1,item2,...)]
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
// Find the list named `strum_discriminants`
|
||||
.filter(|list| list.path.is_ident("strum_discriminants"))
|
||||
// If there are multiple attributes, we combine them all together.
|
||||
.flat_map(|list| list.expand_inner())
|
||||
let discriminant_attrs = type_meta
|
||||
.find_attribute("strum_discriminants")
|
||||
.collect::<Vec<&syn::Meta>>();
|
||||
|
||||
let derives = discriminant_attrs.iter()
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
.filter(|list| list.path.is_ident("derive"))
|
||||
.flat_map(|list| list.expand_inner())
|
||||
let derives = discriminant_attrs
|
||||
.find_attribute("derive")
|
||||
.map(|meta| meta.path())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -41,7 +34,16 @@ pub fn enum_discriminants_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
Span::call_site()
|
||||
));
|
||||
|
||||
let discriminants_name = unique_meta_list(discriminant_attrs.iter().map(|&m| m), "name")
|
||||
let discriminants_name = discriminant_attrs.iter()
|
||||
.filter_map(|meta| meta.try_metalist())
|
||||
.filter(|list| list.path.is_ident("name"))
|
||||
// We want exactly zero or one items. Start with the assumption we have zero, i.e. None
|
||||
// Then set our output to the first value we see. If fold is called again and we already
|
||||
// have a value, panic.
|
||||
.fold(None, |acc, val| match acc {
|
||||
Some(_) => panic!("Expecting a single attribute 'name' in EnumDiscriminants."),
|
||||
None => Some(val),
|
||||
})
|
||||
.map(|meta| meta.expand_inner())
|
||||
.and_then(|metas| metas.into_iter().map(|meta| meta.path()).next())
|
||||
.unwrap_or(&default_name);
|
||||
|
@ -17,8 +17,8 @@ pub fn enum_message_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
for variant in variants {
|
||||
let meta = extract_meta(&variant.attrs);
|
||||
let messages = meta.unique_attr("strum", "message");
|
||||
let detailed_messages = meta.unique_attr("strum", "detailed_message");
|
||||
let messages = meta.find_unique_property("strum", "message");
|
||||
let detailed_messages = meta.find_unique_property("strum", "detailed_message");
|
||||
let ident = &variant.ident;
|
||||
|
||||
use syn::Fields::*;
|
||||
@ -30,7 +30,7 @@ pub fn enum_message_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
// You can't disable getting the serializations.
|
||||
{
|
||||
let mut serialization_variants = meta.extract_attrs("strum", "serialize");
|
||||
let mut serialization_variants = meta.find_properties("strum", "serialize");
|
||||
if serialization_variants.len() == 0 {
|
||||
serialization_variants.push(ident.to_string());
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
use crate::helpers::{convert_case, extract_meta, MetaIteratorHelpers};
|
||||
use crate::helpers::{CaseStyleHelpers, extract_meta, MetaIteratorHelpers};
|
||||
|
||||
pub fn enum_variant_names_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
@ -14,12 +14,12 @@ pub fn enum_variant_names_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
// Derives for the generated enum
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let case_style = type_meta.unique_attr("strum", "serialize_all")
|
||||
let case_style = type_meta.find_unique_property("strum", "serialize_all")
|
||||
.map(|style| CaseStyle::from(style.as_ref()));
|
||||
|
||||
let names = variants
|
||||
.iter()
|
||||
.map(|v| convert_case(&v.ident, case_style))
|
||||
.map(|v| v.ident.convert_case(case_style))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
|
@ -1,10 +1,14 @@
|
||||
pub mod as_ref_str;
|
||||
pub mod display;
|
||||
|
||||
pub mod enum_count;
|
||||
pub mod enum_discriminants;
|
||||
pub mod enum_iter;
|
||||
pub mod enum_messages;
|
||||
pub mod enum_properties;
|
||||
pub mod enum_variant_names;
|
||||
pub mod from_string;
|
||||
pub mod to_string;
|
||||
|
||||
mod strings;
|
||||
|
||||
pub use self::strings::as_ref_str;
|
||||
pub use self::strings::display;
|
||||
pub use self::strings::from_string;
|
||||
pub use self::strings::to_string;
|
||||
|
@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
use helpers::{convert_case, extract_meta, MetaIteratorHelpers};
|
||||
use helpers::{CaseStyleHelpers, extract_meta, MetaIteratorHelpers};
|
||||
|
||||
fn get_arms(ast: &syn::DeriveInput) -> Vec<TokenStream> {
|
||||
let name = &ast.ident;
|
||||
@ -13,7 +13,7 @@ fn get_arms(ast: &syn::DeriveInput) -> Vec<TokenStream> {
|
||||
};
|
||||
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let case_style = type_meta.unique_attr("strum", "serialize_all")
|
||||
let case_style = type_meta.find_unique_property("strum", "serialize_all")
|
||||
.map(|style| CaseStyle::from(style.as_ref()));
|
||||
|
||||
for variant in variants {
|
||||
@ -28,16 +28,16 @@ fn get_arms(ast: &syn::DeriveInput) -> Vec<TokenStream> {
|
||||
// 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) = meta.unique_attr("strum", "to_string") {
|
||||
let output = if let Some(n) = meta.find_unique_property("strum", "to_string") {
|
||||
n
|
||||
} else {
|
||||
let mut attrs = meta.extract_attrs("strum", "serialize");
|
||||
let mut attrs = meta.find_properties("strum", "serialize");
|
||||
// We always take the longest one. This is arbitary, but is *mostly* deterministic
|
||||
attrs.sort_by_key(|s| s.len());
|
||||
if let Some(n) = attrs.pop() {
|
||||
n
|
||||
} else {
|
||||
convert_case(ident, case_style)
|
||||
ident.convert_case(case_style)
|
||||
}
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
use helpers::{convert_case, extract_meta, MetaIteratorHelpers};
|
||||
use helpers::{CaseStyleHelpers, extract_meta, MetaIteratorHelpers};
|
||||
|
||||
pub fn display_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
@ -13,7 +13,7 @@ pub fn display_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let case_style = type_meta.unique_attr("strum", "serialize_all")
|
||||
let case_style = type_meta.find_unique_property("strum", "serialize_all")
|
||||
.map(|style| CaseStyle::from(style.as_ref()));
|
||||
|
||||
let mut arms = Vec::new();
|
||||
@ -27,16 +27,16 @@ pub fn display_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
}
|
||||
|
||||
// Look at all the serialize attributes.
|
||||
let output = if let Some(n) = meta.unique_attr("strum", "to_string") {
|
||||
let output = if let Some(n) = meta.find_unique_property("strum", "to_string") {
|
||||
n
|
||||
} else {
|
||||
let mut attrs = meta.extract_attrs("strum", "serialize");
|
||||
let mut attrs = meta.find_properties("strum", "serialize");
|
||||
// We always take the longest one. This is arbitary, but is *mostly* deterministic
|
||||
attrs.sort_by_key(|s| s.len());
|
||||
if let Some(n) = attrs.pop() {
|
||||
n
|
||||
} else {
|
||||
convert_case(ident, case_style)
|
||||
ident.convert_case(case_style)
|
||||
}
|
||||
};
|
||||
|
@ -2,8 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
// use helpers::{convert_case, extract_attrs, extract_meta, is_disabled, unique_attr, MetaIteratorHelpers};
|
||||
use crate::helpers::{convert_case, extract_meta, MetaIteratorHelpers};
|
||||
use crate::helpers::{CaseStyleHelpers, extract_meta, MetaIteratorHelpers};
|
||||
|
||||
pub fn from_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
@ -14,7 +13,7 @@ pub fn from_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let case_style = type_meta.unique_attr("strum", "serialize_all")
|
||||
let case_style = type_meta.find_unique_property("strum", "serialize_all")
|
||||
.map(|style| CaseStyle::from(style.as_ref()));
|
||||
|
||||
let mut has_default = false;
|
||||
@ -27,18 +26,18 @@ pub fn from_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let meta = extract_meta(&variant.attrs);
|
||||
|
||||
// Look at all the serialize attributes.
|
||||
// let mut attrs = extract_attrs(&meta, "strum", "serialize");
|
||||
// attrs.extend(extract_attrs(&meta, "strum", "to_string"));
|
||||
// let mut attrs = find_properties(&meta, "strum", "serialize");
|
||||
// attrs.extend(find_properties(&meta, "strum", "to_string"));
|
||||
|
||||
let mut attrs = meta.extract_attrs("strum", "serialize");
|
||||
attrs.extend(meta.extract_attrs("strum", "to_string"));
|
||||
let mut attrs = meta.find_properties("strum", "serialize");
|
||||
attrs.extend(meta.find_properties("strum", "to_string"));
|
||||
|
||||
// if is_disabled(&meta) {
|
||||
if meta.is_disabled() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if meta.unique_attr("strum", "default").map_or(false, |s| s == "true") {
|
||||
if meta.find_unique_property("strum", "default").map_or(false, |s| s == "true") {
|
||||
if has_default {
|
||||
panic!("Can't have multiple default variants");
|
||||
}
|
||||
@ -61,7 +60,7 @@ pub fn from_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
// If we don't have any custom variants, add the default serialized name.
|
||||
if attrs.len() == 0 {
|
||||
attrs.push(convert_case(ident, case_style));
|
||||
attrs.push(ident.convert_case(case_style));
|
||||
}
|
||||
|
||||
let params = match variant.fields {
|
4
strum_macros/src/macros/strings/mod.rs
Normal file
4
strum_macros/src/macros/strings/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod as_ref_str;
|
||||
pub mod display;
|
||||
pub mod from_string;
|
||||
pub mod to_string;
|
@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
use crate::helpers::case_style::CaseStyle;
|
||||
use crate::helpers::{convert_case, extract_meta, MetaIteratorHelpers};
|
||||
use crate::helpers::{CaseStyleHelpers, extract_meta, MetaIteratorHelpers};
|
||||
|
||||
pub fn to_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
@ -13,7 +13,7 @@ pub fn to_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
let type_meta = extract_meta(&ast.attrs);
|
||||
let case_style = type_meta.unique_attr( "strum", "serialize_all")
|
||||
let case_style = type_meta.find_unique_property( "strum", "serialize_all")
|
||||
.map(|style| CaseStyle::from(style.as_ref()));
|
||||
|
||||
let mut arms = Vec::new();
|
||||
@ -27,16 +27,16 @@ pub fn to_string_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
}
|
||||
|
||||
// Look at all the serialize attributes.
|
||||
let output = if let Some(n) = meta.unique_attr("strum", "to_string") {
|
||||
let output = if let Some(n) = meta.find_unique_property("strum", "to_string") {
|
||||
n
|
||||
} else {
|
||||
let mut attrs = meta.extract_attrs("strum", "serialize");
|
||||
let mut attrs = meta.find_properties("strum", "serialize");
|
||||
// We always take the longest one. This is arbitary, but is *mostly* deterministic
|
||||
attrs.sort_by_key(|s| s.len());
|
||||
if let Some(n) = attrs.pop() {
|
||||
n
|
||||
} else {
|
||||
convert_case(ident, case_style)
|
||||
ident.convert_case(case_style)
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user