rename and rename_all attributes
This commit is contained in:
1 parent
5bd28d6774
commit
a3137d86c2
4 files changed
+51
-17
No files matched your search
@@ -7,8 +7,9 @@ use syn::{DataEnum, Fields, Attribute};
|
|||||||
|
|
||||||
use crate::attribute::{Dict, Value};
|
use crate::attribute::{Dict, Value};
|
||||||
use crate::error::{MacroError, MacroResult};
|
use crate::error::{MacroError, MacroResult};
|
||||||
|
use crate::rename::RenameVariant;
|
||||||
use crate::{TokenStream2, CASE_SENSITIVE};
|
use crate::{TokenStream2, CASE_SENSITIVE};
|
||||||
use crate::{CASE_INSENSITIVE, CRATE_ATTR, IGNORE, NAME, OTHER};
|
use crate::{CASE_INSENSITIVE, RENAME, RENAME_ALL, CRATE_ATTR, IGNORE, NAME, OTHER};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct Enum<'a> {
|
pub(crate) struct Enum<'a> {
|
||||||
@@ -192,19 +193,20 @@ pub(crate) fn parse_enum<'a>(data: &'a DataEnum, attrs: &'a [Attribute]) -> Macr
|
|||||||
let mut taken_sensitive_names = HashSet::new();
|
let mut taken_sensitive_names = HashSet::new();
|
||||||
let mut other_variant = false;
|
let mut other_variant = false;
|
||||||
|
|
||||||
let global_case_insensitive = {
|
let mut global_dict = Dict::from_attrs(CRATE_ATTR, attrs)?;
|
||||||
let mut dict = Dict::from_attrs(CRATE_ATTR, attrs)?;
|
|
||||||
|
|
||||||
let (global_case_insensitive, _) = dict.remove_typed_or_default(
|
let (global_case_insensitive, _) = global_dict.remove_typed_or_default(
|
||||||
CASE_INSENSITIVE,
|
CASE_INSENSITIVE,
|
||||||
(false, data.enum_token.span()),
|
(false, data.enum_token.span()),
|
||||||
Value::value_bool,
|
Value::value_bool,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
dict.assert_empty()?;
|
let global_rename = global_dict.remove_typed(RENAME_ALL, Value::value_string)?
|
||||||
|
.map(|(global_rename, span)| RenameVariant::from_str(&global_rename, span))
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
global_case_insensitive
|
global_dict.assert_empty()?;
|
||||||
};
|
drop(global_dict);
|
||||||
|
|
||||||
for variant in data.variants.iter() {
|
for variant in data.variants.iter() {
|
||||||
let variant_span = variant.span();
|
let variant_span = variant.span();
|
||||||
@@ -213,10 +215,7 @@ pub(crate) fn parse_enum<'a>(data: &'a DataEnum, attrs: &'a [Attribute]) -> Macr
|
|||||||
let mut dict = Dict::from_attrs(CRATE_ATTR, &variant.attrs)?;
|
let mut dict = Dict::from_attrs(CRATE_ATTR, &variant.attrs)?;
|
||||||
|
|
||||||
// Convert the values in the Dict to the appropriate types
|
// Convert the values in the Dict to the appropriate types
|
||||||
let name_opt = dict.remove_typed(
|
let name_opt = dict.remove_typed(NAME, Value::value_string)?;
|
||||||
NAME,
|
|
||||||
Value::value_string
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let (other, other_span) = dict.remove_typed_or_default(
|
let (other, other_span) = dict.remove_typed_or_default(
|
||||||
OTHER,
|
OTHER,
|
||||||
@@ -257,6 +256,11 @@ pub(crate) fn parse_enum<'a>(data: &'a DataEnum, attrs: &'a [Attribute]) -> Macr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let rename = dict.remove_typed(RENAME, Value::value_string)?
|
||||||
|
.map(|(rename, span)| RenameVariant::from_str(&rename, span))
|
||||||
|
.transpose()?
|
||||||
|
.or(global_rename);
|
||||||
|
|
||||||
// Return an error if there are any unrecognised keys in the Dict
|
// Return an error if there are any unrecognised keys in the Dict
|
||||||
dict.assert_empty()?;
|
dict.assert_empty()?;
|
||||||
|
|
||||||
@@ -318,7 +322,14 @@ pub(crate) fn parse_enum<'a>(data: &'a DataEnum, attrs: &'a [Attribute]) -> Macr
|
|||||||
// Use the str name if one is provided, otherwise use the variant's name
|
// Use the str name if one is provided, otherwise use the variant's name
|
||||||
let (name, name_span) = match name_opt {
|
let (name, name_span) = match name_opt {
|
||||||
Some((name, name_span)) => (name, name_span),
|
Some((name, name_span)) => (name, name_span),
|
||||||
None => (variant.ident.to_string(), variant.ident.span()),
|
None => {
|
||||||
|
let name_span = variant.ident.span();
|
||||||
|
let mut name = variant.ident.to_string();
|
||||||
|
if let Some(rename) = rename {
|
||||||
|
name = rename.apply(&name);
|
||||||
|
}
|
||||||
|
(name, name_span)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do not allow duplicate names
|
// Do not allow duplicate names
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ const OTHER: &'static str = "other";
|
|||||||
const IGNORE: &'static str = "ignore";
|
const IGNORE: &'static str = "ignore";
|
||||||
const CASE_INSENSITIVE: &'static str = "case_insensitive";
|
const CASE_INSENSITIVE: &'static str = "case_insensitive";
|
||||||
const CASE_SENSITIVE: &'static str = "case_sensitive";
|
const CASE_SENSITIVE: &'static str = "case_sensitive";
|
||||||
|
const RENAME: &'static str = "rename";
|
||||||
|
const RENAME_ALL: &'static str = "rename_all";
|
||||||
|
|
||||||
type TokenStream2 = proc_macro2::TokenStream;
|
type TokenStream2 = proc_macro2::TokenStream;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl RenameVariant {
|
|||||||
match s {
|
match s {
|
||||||
"lowercase" => Ok(Self::Lower),
|
"lowercase" => Ok(Self::Lower),
|
||||||
"UPPERCASE" => Ok(Self::Upper),
|
"UPPERCASE" => Ok(Self::Upper),
|
||||||
"PascalCase" => Ok(Self::Upper),
|
"PascalCase" => Ok(Self::Pascal),
|
||||||
"camelCase" => Ok(Self::Camel),
|
"camelCase" => Ok(Self::Camel),
|
||||||
"snake_case" => Ok(Self::Snake),
|
"snake_case" => Ok(Self::Snake),
|
||||||
"SCREAMING_SNAKE_CASE" => Ok(Self::ScreamingSnake),
|
"SCREAMING_SNAKE_CASE" => Ok(Self::ScreamingSnake),
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
use enumscribe::*;
|
||||||
|
|
||||||
|
#[derive(ScribeStaticStr, TryUnscribe, PartialEq, Eq, Debug)]
|
||||||
|
#[enumscribe(rename_all = "snake_case")]
|
||||||
|
enum Bird {
|
||||||
|
BlackRedstart,
|
||||||
|
#[enumscribe(case_insensitive)]
|
||||||
|
GardenWarbler,
|
||||||
|
#[enumscribe(rename = "SCREAMING-KEBAB-CASE")]
|
||||||
|
BarnacleGoose,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(Bird::BlackRedstart.scribe(), "black_redstart");
|
||||||
|
assert_eq!(Bird::GardenWarbler.scribe(), "garden_warbler");
|
||||||
|
assert_eq!(Bird::BarnacleGoose.scribe(), "BARNACLE-GOOSE");
|
||||||
|
|
||||||
|
assert_eq!(Bird::try_unscribe("black_redstart").unwrap(), Bird::BlackRedstart);
|
||||||
|
assert_eq!(Bird::try_unscribe("gArDeN_wArBlEr").unwrap(), Bird::GardenWarbler);
|
||||||
|
assert_eq!(Bird::try_unscribe("BARNACLE-GOOSE").unwrap(), Bird::BarnacleGoose);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user