1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//!
//! Utilities for manipulating identifiers, including keyword handling.
//!
/// Define a private namespace for all its items.
mod private
{
use crate :: *; // Use crate's prelude/exposed items
use convert_case ::Casing;
use proc_macro2 ::Ident;
// use syn ::spanned ::Spanned; // Needed for span
/// Ensures keyword safety by applying raw identifier escaping when needed to prevent compilation errors.
///
/// Preserves the span of the original identifier.
/// Requires the `kw` feature.
///
/// # Example
/// ```rust
/// use macro_tools :: { syn, format_ident, ident };
///
/// let ident_normal = format_ident!( "my_var" );
/// let ident_keyword = format_ident!( "fn" );
///
/// let got_normal = ident ::ident_maybe_raw( &ident_normal );
/// let got_keyword = ident ::ident_maybe_raw( &ident_keyword );
///
/// assert_eq!( got_normal.to_string(), "my_var" );
/// assert_eq!( got_keyword.to_string(), "r#fn" );
/// ```
#[ must_use ]
pub fn ident_maybe_raw(ident: &syn ::Ident) -> Ident
{
let name = ident.to_string();
if kw ::is(&name)
{
// Use r# prefix if the name is a keyword
format_ident!("r#{}", name, span = ident.span())
} else {
// Otherwise, use the name directly (cloned)
ident.clone()
}
}
/// Transforms identifier casing while preserving keyword safety to support code generation scenarios
/// that require consistent naming conventions.
///
/// # Arguments
///
/// * `original` - The original `syn ::Ident` to convert.
/// * `case` - The target `convert_case ::Case` to convert the identifier to.
///
/// # Returns
///
/// Maintains span information and raw identifier semantics to ensure generated code correctness.
///
/// # Examples
///
/// ```rust
/// use macro_tools :: { syn, format_ident };
/// use convert_case ::Case;
///
/// let ident_normal = format_ident!( "my_variable" );
/// let ident_keyword = format_ident!( "r#fn" );
///
/// // Convert to PascalCase
/// let got_pascal = macro_tools ::ident ::cased_ident_from_ident( &ident_normal, Case ::Pascal );
/// assert_eq!( got_pascal.to_string(), "MyVariable" );
///
/// // Convert a raw identifier to SnakeCase
/// let got_snake_raw = macro_tools ::ident ::cased_ident_from_ident( &ident_keyword, Case ::Snake );
/// assert_eq!( got_snake_raw.to_string(), "r#fn" );
///
/// // Convert a normal identifier that becomes a keyword in the new case
/// let ident_struct = format_ident!( "struct" );
/// let got_pascal_keyword = macro_tools ::ident ::cased_ident_from_ident( &ident_struct, Case ::Pascal );
/// assert_eq!( got_pascal_keyword.to_string(), "Struct" ); // qqq: "Struct" is not a keyword, so `r#` is not added.
/// ```
#[ must_use ]
pub fn cased_ident_from_ident(original: &syn ::Ident, case: convert_case ::Case) -> syn ::Ident
{
let original_str = original.to_string();
let had_raw_prefix = original_str.starts_with("r#");
let core_str = if had_raw_prefix { &original_str[2..] } else { &original_str };
let cased_str = core_str.to_case(case);
if kw ::is(&cased_str)
{
syn ::Ident ::new_raw(&cased_str, original.span())
} else {
syn ::Ident ::new(&cased_str, original.span())
}
}
}
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use own :: *;
/// Own namespace of the module.
#[ allow( unused_imports ) ]
pub mod own
{
use super :: *;
#[ doc( inline ) ]
pub use orphan :: *;
#[ doc( inline ) ]
pub use private ::ident_maybe_raw;
#[ doc( inline ) ]
pub use private ::cased_ident_from_ident;
}
/// Orphan namespace of the module.
#[ allow( unused_imports ) ]
pub mod orphan
{
use super :: *;
#[ doc( inline ) ]
pub use exposed :: *;
}
/// Exposed namespace of the module.
#[ allow( unused_imports ) ]
pub mod exposed
{
use super :: *;
pub use super ::super ::ident; // Use the new module name
#[ doc( inline ) ]
pub use prelude :: *;
}
/// Prelude to use essentials: `use my_module ::prelude :: *`.
#[ allow( unused_imports ) ]
pub mod prelude
{
use super :: *;
}