use macro_tools :: { syn, quote ::format_ident, ident };
use convert_case :: { Case, Casing };
pub fn variant_to_method_name(variant_ident: &syn ::Ident) -> syn ::Ident
{
let variant_str = variant_ident.to_string();
if let Some(actual_name) = variant_str.strip_prefix("r#")
{
let snake_case_name = actual_name.to_case(Case ::Snake);
if is_rust_keyword(&snake_case_name)
{
format_ident!("r#{}", snake_case_name, span = variant_ident.span())
} else {
format_ident!("{}", snake_case_name, span = variant_ident.span())
}
} else {
let snake_case_name = variant_str.to_case(Case ::Snake);
if is_rust_keyword(&snake_case_name)
{
format_ident!("r#{}", snake_case_name, span = variant_ident.span())
} else {
format_ident!("{}", snake_case_name, span = variant_ident.span())
}
}
}
fn is_rust_keyword(s: &str) -> bool
{
matches!(s,
"as" | "break" | "const" | "continue" | "crate" | "else" | "enum" | "extern" |
"false" | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "match" |
"mod" | "move" | "mut" | "pub" | "ref" | "return" | "self" | "Self" |
"static" | "struct" | "super" | "trait" | "true" | "type" | "unsafe" |
"use" | "where" | "while" | "async" | "await" | "dyn" | "abstract" |
"become" | "box" | "do" | "final" | "macro" | "override" | "priv" |
"typeof" | "unsized" | "virtual" | "yield" | "try"
)
}
#[ allow( dead_code ) ]
pub fn field_to_param_name(field_ident: &syn ::Ident) -> syn ::Ident
{
ident ::ident_maybe_raw(field_ident)
}
pub fn strip_raw_prefix_for_compound_ident(ident: &syn ::Ident) -> String
{
let ident_str = ident.to_string();
if let Some(stripped) = ident_str.strip_prefix("r#")
{
stripped.to_string()
} else {
ident_str
}
}
#[ allow( dead_code ) ]
pub fn type_to_constructor_name(type_ident: &syn ::Ident) -> syn ::Ident
{
let type_str = type_ident.to_string();
if let Some(actual_name) = type_str.strip_prefix("r#")
{
let snake_case_name = actual_name.to_case(Case ::Snake);
if is_rust_keyword(&snake_case_name)
{
format_ident!("r#{}", snake_case_name, span = type_ident.span())
} else {
format_ident!("{}", snake_case_name, span = type_ident.span())
}
} else {
let snake_case_name = type_str.to_case(Case ::Snake);
if is_rust_keyword(&snake_case_name)
{
format_ident!("r#{}", snake_case_name, span = type_ident.span())
} else {
format_ident!("{}", snake_case_name, span = type_ident.span())
}
}
}
#[ cfg( test ) ]
mod tests
{
use super :: *;
use macro_tools ::quote ::format_ident;
#[ test ]
fn test_variant_to_method_name_normal()
{
let variant = format_ident!( "MyVariant" );
let method = variant_to_method_name( &variant );
assert_eq!( method.to_string(), "my_variant" );
}
#[ test ]
fn test_variant_to_method_name_keyword()
{
let variant = format_ident!( "Break" );
let method = variant_to_method_name( &variant );
assert_eq!( method.to_string(), "r#break" );
}
#[ test ]
fn test_is_rust_keyword()
{
assert!( is_rust_keyword( "break" ) );
assert!( is_rust_keyword( "move" ) );
assert!( is_rust_keyword( "async" ) );
assert!( !is_rust_keyword( "normal" ) );
assert!( !is_rust_keyword( "value" ) );
}
#[ test ]
fn test_type_to_constructor_name()
{
let type_name = format_ident!( "MyStruct" );
let constructor = type_to_constructor_name( &type_name );
assert_eq!( constructor.to_string(), "my_struct" );
}
}