Compare commits
5
Commits
803e582012
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e3e5d8496 | ||
|
|
6f9f6075e0 | ||
|
|
a3137d86c2 | ||
|
|
5bd28d6774 | ||
|
|
16ae2d403e |
No files matched your search
@@ -11,7 +11,7 @@ Add to your Cargo.toml file:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
enumscribe = "0.3"
|
enumscribe = "0.4"
|
||||||
```
|
```
|
||||||
|
|
||||||
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "enumscribe"
|
name = "enumscribe"
|
||||||
version = "0.3.1"
|
version = "0.4.0"
|
||||||
authors = ["Tom Panton <pantonshire@gmail.com>"]
|
authors = ["Tom Panton <pantonshire@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -11,7 +11,7 @@ categories = ["encoding"]
|
|||||||
keywords = ["enum", "derive", "serde"]
|
keywords = ["enum", "derive", "serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
enumscribe_derive = { version = "0.3.1", path = "../enumscribe_derive", default-features = false, optional = true }
|
enumscribe_derive = { version = "0.4.0", path = "../enumscribe_derive", default-features = false, optional = true }
|
||||||
serde = { version = "1.0", default-features = false, optional = true }
|
serde = { version = "1.0", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Add to your Cargo.toml file:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
enumscribe = "0.3"
|
enumscribe = "0.4"
|
||||||
```
|
```
|
||||||
|
|
||||||
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
use core::{str, ops::Deref, borrow::Borrow, fmt};
|
use core::{str, ops::Deref, borrow::Borrow, fmt};
|
||||||
|
|
||||||
/// TODO: documentation
|
/// A string type which is either borrowed or stores up to `N` bytes of string data inline.
|
||||||
pub enum CowCappedString<'a, const N: usize> {
|
pub enum CowCappedString<'a, const N: usize> {
|
||||||
/// TODO: documentation
|
/// A reference to string data stored elsewhere.
|
||||||
Borrowed(&'a str),
|
Borrowed(&'a str),
|
||||||
/// TODO: documentation
|
/// The string data is stored inline.
|
||||||
Owned(CappedString<N>),
|
Owned(CappedString<N>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "enumscribe_derive"
|
name = "enumscribe_derive"
|
||||||
version = "0.3.1"
|
version = "0.4.0"
|
||||||
authors = ["Tom Panton <pantonshire@gmail.com>"]
|
authors = ["Tom Panton <pantonshire@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Add to your Cargo.toml file:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
enumscribe = "0.3"
|
enumscribe = "0.4"
|
||||||
```
|
```
|
||||||
|
|
||||||
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
Derive macros and [`serde`](https://crates.io/crates/serde) support are enabled by default. They can be disabled by
|
||||||
|
|||||||
@@ -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, _) = global_dict.remove_typed_or_default(
|
||||||
|
CASE_INSENSITIVE,
|
||||||
|
(false, data.enum_token.span()),
|
||||||
|
Value::value_bool,
|
||||||
|
)?;
|
||||||
|
|
||||||
let (global_case_insensitive, _) = dict.remove_typed_or_default(
|
let global_rename = global_dict.remove_typed(RENAME_ALL, Value::value_string)?
|
||||||
CASE_INSENSITIVE,
|
.map(|(global_rename, span)| RenameVariant::from_str(&global_rename, span))
|
||||||
(false, data.enum_token.span()),
|
.transpose()?;
|
||||||
Value::value_bool,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
dict.assert_empty()?;
|
global_dict.assert_empty()?;
|
||||||
|
drop(global_dict);
|
||||||
global_case_insensitive
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl MacroError {
|
|||||||
pub(crate) fn to_token_stream2(&self) -> TokenStream2 {
|
pub(crate) fn to_token_stream2(&self) -> TokenStream2 {
|
||||||
let message = &self.message;
|
let message = &self.message;
|
||||||
quote_spanned! {
|
quote_spanned! {
|
||||||
self.span => ::std::compile_error!(#message);
|
self.span => ::core::compile_error!(#message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use crate::enums::{Enum, Variant, VariantType};
|
|||||||
mod attribute;
|
mod attribute;
|
||||||
mod enums;
|
mod enums;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod rename;
|
||||||
|
|
||||||
const CRATE_ATTR: &'static str = "enumscribe";
|
const CRATE_ATTR: &'static str = "enumscribe";
|
||||||
|
|
||||||
@@ -27,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;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,236 @@
|
|||||||
|
use proc_macro2::Span;
|
||||||
|
|
||||||
|
use crate::error::{MacroResult, MacroError};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub(crate) enum RenameVariant {
|
||||||
|
Lower,
|
||||||
|
Upper,
|
||||||
|
Pascal,
|
||||||
|
Camel,
|
||||||
|
Snake,
|
||||||
|
ScreamingSnake,
|
||||||
|
Kebab,
|
||||||
|
ScreamingKebab,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenameVariant {
|
||||||
|
pub(crate) fn from_str(s: &str, span: Span) -> MacroResult<Self> {
|
||||||
|
// Shame we can't use enumscribe for this...
|
||||||
|
match s {
|
||||||
|
"lowercase" => Ok(Self::Lower),
|
||||||
|
"UPPERCASE" => Ok(Self::Upper),
|
||||||
|
"PascalCase" => Ok(Self::Pascal),
|
||||||
|
"camelCase" => Ok(Self::Camel),
|
||||||
|
"snake_case" => Ok(Self::Snake),
|
||||||
|
"SCREAMING_SNAKE_CASE" => Ok(Self::ScreamingSnake),
|
||||||
|
"kebab-case" => Ok(Self::Kebab),
|
||||||
|
"SCREAMING-KEBAB-CASE" => Ok(Self::ScreamingKebab),
|
||||||
|
_ => Err(MacroError::new(
|
||||||
|
format!(
|
||||||
|
"invalid case {:?} (allowed values are: \
|
||||||
|
lowercase, \
|
||||||
|
UPPERCASE, \
|
||||||
|
PascalCase, \
|
||||||
|
camelCase, \
|
||||||
|
snake_case, \
|
||||||
|
SCREAMING_SNAKE_CASE, \
|
||||||
|
kebab-case, \
|
||||||
|
SCREAMING-KEBAB-CASE)",
|
||||||
|
s
|
||||||
|
),
|
||||||
|
span
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn apply(self, s: &str) -> String {
|
||||||
|
match self {
|
||||||
|
RenameVariant::Lower => s.to_lowercase(),
|
||||||
|
RenameVariant::Upper => s.to_uppercase(),
|
||||||
|
RenameVariant::Pascal => PascalCase.convert_enum_variant(s),
|
||||||
|
RenameVariant::Camel => CamelCase.convert_enum_variant(s),
|
||||||
|
RenameVariant::Snake => SnakeCase(CharCase::Lower).convert_enum_variant(s),
|
||||||
|
RenameVariant::ScreamingSnake => SnakeCase(CharCase::Upper).convert_enum_variant(s),
|
||||||
|
RenameVariant::Kebab => KebabCase(CharCase::Lower).convert_enum_variant(s),
|
||||||
|
RenameVariant::ScreamingKebab => KebabCase(CharCase::Upper).convert_enum_variant(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait WordAwareCase {
|
||||||
|
fn convert_enum_variant(&self, s: &str) -> String {
|
||||||
|
let mut converted = String::new();
|
||||||
|
let mut component = String::new();
|
||||||
|
let mut prev_case = Option::None;
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
let case = CharCase::of(c);
|
||||||
|
|
||||||
|
let (push_component, push_char) = {
|
||||||
|
if matches!((prev_case, case), (Some(CharCase::Lower), Some(CharCase::Upper))) {
|
||||||
|
(true, true)
|
||||||
|
} else if c == '_' {
|
||||||
|
(true, false)
|
||||||
|
} else {
|
||||||
|
(false, true)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if push_component && !component.is_empty() {
|
||||||
|
self.push_word(&mut converted, &component);
|
||||||
|
component.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if push_char {
|
||||||
|
component.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_case = case;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !component.is_empty() {
|
||||||
|
self.push_word(&mut converted, &component);
|
||||||
|
}
|
||||||
|
|
||||||
|
converted
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_word(&self, buf: &mut String, word: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PascalCase;
|
||||||
|
|
||||||
|
impl WordAwareCase for PascalCase {
|
||||||
|
fn push_word(&self, buf: &mut String, word: &str) {
|
||||||
|
if let Some((head, tail)) = str_head_tail(word) {
|
||||||
|
buf.extend(head.to_uppercase());
|
||||||
|
buf.push_str(&tail.to_lowercase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CamelCase;
|
||||||
|
|
||||||
|
impl WordAwareCase for CamelCase {
|
||||||
|
fn push_word(&self, buf: &mut String, word: &str) {
|
||||||
|
if buf.is_empty() {
|
||||||
|
buf.push_str(&word.to_lowercase());
|
||||||
|
} else if let Some((head, tail)) = str_head_tail(word) {
|
||||||
|
buf.extend(head.to_uppercase());
|
||||||
|
buf.push_str(&tail.to_lowercase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SnakeCase(CharCase);
|
||||||
|
|
||||||
|
impl WordAwareCase for SnakeCase {
|
||||||
|
fn push_word(&self, buf: &mut String, word: &str) {
|
||||||
|
if !buf.is_empty() {
|
||||||
|
buf.push('_');
|
||||||
|
}
|
||||||
|
buf.push_str(&self.0.convert(word));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KebabCase(CharCase);
|
||||||
|
|
||||||
|
impl WordAwareCase for KebabCase {
|
||||||
|
fn push_word(&self, buf: &mut String, word: &str) {
|
||||||
|
if !buf.is_empty() {
|
||||||
|
buf.push('-');
|
||||||
|
}
|
||||||
|
buf.push_str(&self.0.convert(word));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
enum CharCase {
|
||||||
|
Upper,
|
||||||
|
Lower,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CharCase {
|
||||||
|
fn of(c: char) -> Option<Self> {
|
||||||
|
if c.is_uppercase() {
|
||||||
|
Some(Self::Upper)
|
||||||
|
} else if c.is_lowercase() {
|
||||||
|
Some(Self::Lower)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(self, s: &str) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Upper => s.to_uppercase(),
|
||||||
|
Self::Lower => s.to_lowercase(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn str_head_tail(s: &str) -> Option<(char, &str)> {
|
||||||
|
let head = s.chars().next()?;
|
||||||
|
let tail = &s[head.len_utf8()..];
|
||||||
|
Some((head, tail))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::{PascalCase, CamelCase, SnakeCase, KebabCase, CharCase, WordAwareCase};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pascal_case() {
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant(""), "");
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant("foo"), "Foo");
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant("fooBaa"), "FooBaa");
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant("FooBaa"), "FooBaa");
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant("foo_baa"), "FooBaa");
|
||||||
|
assert_eq!(PascalCase.convert_enum_variant("FOO_BAA"), "FooBaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_camel_case() {
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant(""), "");
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant("foo"), "foo");
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant("fooBaa"), "fooBaa");
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant("FooBaa"), "fooBaa");
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant("foo_baa"), "fooBaa");
|
||||||
|
assert_eq!(CamelCase.convert_enum_variant("FOO_BAA"), "fooBaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_snake_case() {
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant(""), "");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant("foo"), "foo");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant("fooBaa"), "foo_baa");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant("FooBaa"), "foo_baa");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant("foo_baa"), "foo_baa");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Lower).convert_enum_variant("FOO_BAA"), "foo_baa");
|
||||||
|
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant(""), "");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant("foo"), "FOO");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant("fooBaa"), "FOO_BAA");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant("FooBaa"), "FOO_BAA");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant("foo_baa"), "FOO_BAA");
|
||||||
|
assert_eq!(SnakeCase(CharCase::Upper).convert_enum_variant("FOO_BAA"), "FOO_BAA");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_kebab_case() {
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant(""), "");
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant("foo"), "foo");
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant("fooBaa"), "foo-baa");
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant("FooBaa"), "foo-baa");
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant("foo_baa"), "foo-baa");
|
||||||
|
assert_eq!(KebabCase(CharCase::Lower).convert_enum_variant("FOO_BAA"), "foo-baa");
|
||||||
|
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant(""), "");
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant("foo"), "FOO");
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant("fooBaa"), "FOO-BAA");
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant("FooBaa"), "FOO-BAA");
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant("foo_baa"), "FOO-BAA");
|
||||||
|
assert_eq!(KebabCase(CharCase::Upper).convert_enum_variant("FOO_BAA"), "FOO-BAA");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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