Skip to main content

Maintain/Build/
Pascalize.rs

1//=============================================================================//
2// File Path: Element/Maintain/Source/Build/Pascalize.rs
3//=============================================================================//
4// Module: Pascalize
5//
6// Brief Description: Converts kebab-case and snake_case strings to PascalCase.
7//
8// RESPONSIBILITIES:
9// ================
10//
11// Primary:
12// - Convert kebab-case strings to PascalCase
13// - Convert snake_case strings to PascalCase
14// - Handle delimiter-separated strings of any length
15//
16// Secondary:
17// - None
18//
19// ARCHITECTURAL ROLE:
20// ===================
21//
22// Position:
23// - Infrastructure/Utility layer
24// - String transformation utilities
25//
26// Dependencies (What this module requires):
27// - External crates: None
28// - Internal modules: None
29// - Traits implemented: None
30//
31// Dependents (What depends on this module):
32// - Build orchestration functions
33// - Product name generation logic
34// - Bundle identifier generation logic
35//
36// IMPLEMENTATION DETAILS:
37// =======================
38//
39// Design Patterns:
40// - String transformation pattern
41// - Functional pattern
42//
43// Performance Considerations:
44// - Complexity: O(n) - where n is the length of the input string
45// - Memory usage patterns: Creates new String with allocated capacity
46// - Hot path optimizations: None needed
47//
48// Thread Safety:
49// - Thread-safe: Yes (pure function with immutable input and output)
50// - Synchronization mechanisms used: None
51// - Interior mutability considerations: None
52//
53// Error Handling:
54// - Error types returned: None
55// - Recovery strategies: Not applicable
56//
57// EXAMPLES:
58// =========
59//
60// Example 1: Kebab-case conversion
61/// ```rust
62/// use crate::Maintain::Source::Build::Pascalize;
63/// let result = Pascalize("development");
64/// assert_eq!(result, "Development");
65/// ```
66// Example 2: Snake_case conversion
67/// ```rust
68/// use crate::Maintain::Source::Build::Pascalize;
69/// let result = Pascalize("node_environment");
70/// assert_eq!(result, "NodeEnvironment");
71/// ```
72// Example 3: Mixed delimiters
73/// ```rust
74/// use crate::Maintain::Source::Build::Pascalize;
75/// let result = Pascalize("tauri-apps_tauri");
76/// assert_eq!(result, "TauriAppsTauri");
77/// ```
78//
79//=============================================================================//
80// IMPLEMENTATION
81//=============================================================================//
82
83/// Converts a kebab-case or snake_case string to `PascalCase`.
84///
85/// This function processes strings separated by hyphens (`-`) or underscores
86/// (`_`) and converts them to PascalCase by capitalizing the first letter of
87/// each word. The function handles strings with single or multiple delimiters
88/// and filters out empty segments.
89///
90/// # Parameters
91///
92/// * `Text` - The input string to convert (kebab-case or snake_case)
93///
94/// # Returns
95///
96/// A new String in PascalCase format.
97///
98/// # Behavior
99///
100/// - Splits the input on both hyphen (`-`) and underscore (`_`) characters
101/// - Filters out empty segments (from consecutive delimiters)
102/// - Capitalizes the first character of each segment
103/// - Preserves the case of remaining characters
104/// - Joins all segments together without delimiters
105///
106/// # Examples
107///
108/// ```
109/// use crate::Maintain::Source::Build::Pascalize;
110/// assert_eq!(Pascalize("development"), "Development");
111/// assert_eq!(Pascalize("node_environment"), "NodeEnvironment");
112/// assert_eq!(Pascalize("tauri-apps"), "TauriApps");
113/// assert_eq!(Pascalize("my-app_name"), "MyAppName");
114/// ```
115///
116/// # Edge Cases
117///
118/// - Empty string returns an empty string
119/// - Strings with only delimiters return an empty string
120/// - Single word strings are capitalized
121/// - Words already in PascalCase are not modified (no delimiter detection)
122pub fn Pascalize(Text:&str) -> String {
123	Text.split(|c:char| c == '-' || c == '_')
124		.filter(|s| !s.is_empty())
125		.map(|s| {
126			let mut c = s.chars();
127
128			c.next()
129				.map_or(String::new(), |f| f.to_uppercase().collect::<String>() + c.as_str())
130		})
131		.collect()
132}
133
134#[cfg(test)]
135mod tests {
136	use super::*;
137
138	#[test]
139	fn test_kebab_case() {
140		assert_eq!(Pascalize("development"), "Development");
141		assert_eq!(Pascalize("node-version"), "NodeVersion");
142		assert_eq!(Pascalize("tauri-apps"), "TauriApps");
143	}
144
145	#[test]
146	fn test_snake_case() {
147		assert_eq!(Pascalize("node_environment"), "NodeEnvironment");
148		assert_eq!(Pascalize("my_variable_name"), "MyVariableName");
149	}
150
151	#[test]
152	fn test_mixed_delimiters() {
153		assert_eq!(Pascalize("tauri-apps_tauri"), "TauriAppsTauri");
154		assert_eq!(Pascalize("my-app_name"), "MyAppName");
155	}
156
157	#[test]
158	fn test_empty_string() {
159		assert_eq!(Pascalize(""), "");
160	}
161
162	#[test]
163	fn test_only_delimiters() {
164		assert_eq!(Pascalize("---"), "");
165		assert_eq!(Pascalize("___"), "");
166		assert_eq!(Pascalize("-_-"), "");
167	}
168
169	#[test]
170	fn test_single_word() {
171		assert_eq!(Pascalize("hello"), "Hello");
172		assert_eq!(Pascalize("WORLD"), "WORLD");
173	}
174}