Revert case_style.rs

This commit is contained in:
Chris Tsang 2024-05-28 20:18:25 +01:00
parent 33230ab3ad
commit 3e45ac42a2
6 changed files with 146 additions and 27 deletions

View File

@ -1,5 +1,5 @@
use super::case_style::{CaseStyle, CaseStyleHelpers};
use super::util::camel_case_with_escaped_non_uax31; use super::util::camel_case_with_escaped_non_uax31;
use crate::strum::helpers::case_style::{CaseStyle, CaseStyleHelpers};
use heck::ToUpperCamelCase; use heck::ToUpperCamelCase;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote, quote_spanned}; use quote::{format_ident, quote, quote_spanned};

View File

@ -1,4 +1,4 @@
use crate::strum::helpers::case_style::CaseStyle; use super::case_style::CaseStyle;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{quote, quote_spanned, ToTokens}; use quote::{quote, quote_spanned, ToTokens};
use syn::{LitInt, LitStr}; use syn::{LitInt, LitStr};

View File

@ -0,0 +1,134 @@
//! Copied from https://github.com/Peternator7/strum/blob/master/strum_macros/src/helpers/case_style.rs
use heck::{
ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,
};
use std::str::FromStr;
use syn::{
meta::ParseNestedMeta,
parse::{Parse, ParseStream},
Ident, LitStr,
};
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum CaseStyle {
CamelCase,
KebabCase,
MixedCase,
ShoutySnakeCase,
SnakeCase,
TitleCase,
UpperCase,
LowerCase,
ScreamingKebabCase,
PascalCase,
}
const VALID_CASE_STYLES: &[&str] = &[
"camelCase",
"PascalCase",
"kebab-case",
"snake_case",
"SCREAMING_SNAKE_CASE",
"SCREAMING-KEBAB-CASE",
"lowercase",
"UPPERCASE",
"title_case",
"mixed_case",
];
impl Parse for CaseStyle {
fn parse(input: ParseStream) -> syn::Result<Self> {
let text = input.parse::<LitStr>()?;
let val = text.value();
val.as_str().parse().map_err(|_| {
syn::Error::new_spanned(
&text,
format!(
"Unexpected case style for serialize_all: `{}`. Valid values are: `{:?}`",
val, VALID_CASE_STYLES
),
)
})
}
}
impl FromStr for CaseStyle {
type Err = ();
fn from_str(text: &str) -> Result<Self, ()> {
Ok(match text {
"camel_case" | "PascalCase" => CaseStyle::PascalCase,
"camelCase" => CaseStyle::CamelCase,
"snake_case" | "snek_case" => CaseStyle::SnakeCase,
"kebab_case" | "kebab-case" => CaseStyle::KebabCase,
"SCREAMING-KEBAB-CASE" => CaseStyle::ScreamingKebabCase,
"shouty_snake_case" | "shouty_snek_case" | "SCREAMING_SNAKE_CASE" => {
CaseStyle::ShoutySnakeCase
}
"title_case" => CaseStyle::TitleCase,
"mixed_case" => CaseStyle::MixedCase,
"lowercase" => CaseStyle::LowerCase,
"UPPERCASE" => CaseStyle::UpperCase,
_ => return Err(()),
})
}
}
pub trait CaseStyleHelpers {
fn convert_case(&self, case_style: Option<CaseStyle>) -> String;
}
impl CaseStyleHelpers for 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_upper_camel_case(),
CaseStyle::KebabCase => ident_string.to_kebab_case(),
CaseStyle::MixedCase => ident_string.to_lower_camel_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_upper_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
}
}
}
impl<'meta> TryFrom<&ParseNestedMeta<'meta>> for CaseStyle {
type Error = syn::Error;
fn try_from(value: &ParseNestedMeta) -> Result<Self, Self::Error> {
let meta_string_literal: LitStr = value.value()?.parse()?;
let value_string = meta_string_literal.value();
match CaseStyle::from_str(value_string.as_str()) {
Ok(rule) => Ok(rule),
Err(()) => Err(value.error(format!(
"Unknown value for attribute parameter: `{value_string}`. Valid values are: `{VALID_CASE_STYLES:?}`"
))),
}
}
}
#[test]
fn test_convert_case() {
let id = 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)));
}

View File

@ -1,5 +1,5 @@
use super::case_style::{CaseStyle, CaseStyleHelpers};
use super::util::{escape_rust_keyword, trim_starting_raw_identifier}; use super::util::{escape_rust_keyword, trim_starting_raw_identifier};
use crate::strum::helpers::case_style::{CaseStyle, CaseStyleHelpers};
use heck::{ToSnakeCase, ToUpperCamelCase}; use heck::{ToSnakeCase, ToUpperCamelCase};
use proc_macro2::{Ident, Span, TokenStream}; use proc_macro2::{Ident, Span, TokenStream};
use quote::quote; use quote::quote;

View File

@ -3,6 +3,7 @@ mod active_enum_display;
mod active_model; mod active_model;
mod active_model_behavior; mod active_model_behavior;
mod attributes; mod attributes;
mod case_style;
mod column; mod column;
mod derive_iden; mod derive_iden;
mod entity; mod entity;

View File

@ -2,7 +2,6 @@ use heck::{
ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase, ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,
}; };
use std::str::FromStr; use std::str::FromStr;
use syn::meta::ParseNestedMeta;
use syn::{ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
Ident, LitStr, Ident, LitStr,
@ -25,15 +24,15 @@ pub enum CaseStyle {
const VALID_CASE_STYLES: &[&str] = &[ const VALID_CASE_STYLES: &[&str] = &[
"camelCase", "camelCase",
"kebab-case",
"mixed_case",
"SCREAMING_SNAKE_CASE",
"snake_case",
"title_case",
"UPPERCASE",
"lowercase",
"SCREAMING-KEBAB-CASE",
"PascalCase", "PascalCase",
"kebab-case",
"snake_case",
"SCREAMING_SNAKE_CASE",
"SCREAMING-KEBAB-CASE",
"lowercase",
"UPPERCASE",
"title_case",
"mixed_case",
]; ];
impl Parse for CaseStyle { impl Parse for CaseStyle {
@ -110,21 +109,6 @@ impl CaseStyleHelpers for Ident {
} }
} }
impl<'meta> TryFrom<&ParseNestedMeta<'meta>> for CaseStyle {
type Error = syn::Error;
fn try_from(value: &ParseNestedMeta) -> Result<Self, Self::Error> {
let meta_string_literal: LitStr = value.value()?.parse()?;
let value_string = meta_string_literal.value();
match CaseStyle::from_str(value_string.as_str()) {
Ok(rule) => Ok(rule),
Err(()) => Err(value.error(format!(
"Unknown value for attribute parameter: `{value_string}`. Valid values are: `{VALID_CASE_STYLES:?}`"
))),
}
}
}
#[test] #[test]
fn test_convert_case() { fn test_convert_case() {
let id = Ident::new("test_me", proc_macro2::Span::call_site()); let id = Ident::new("test_me", proc_macro2::Span::call_site());