voca_rs/case.rs
1//! Converts the `subject` to a selected case.
2
3/// Converts the `subject` to camel case.
4///
5/// # Arguments
6///
7/// * `subject` - The string to convert to camel case.
8///
9/// # Example
10/// ```
11/// use voca_rs::*;
12/// case::camel_case("bird flight");
13/// // => "birdFlight"
14/// case::camel_case("BirdFlight");
15/// // => "birdFlight"
16/// case::camel_case("-BIRD-FLIGHT-");
17/// // => "birdFlight"
18/// use voca_rs::Voca;
19/// "bird flight"._camel_case();
20/// // => "birdFlight"
21/// ```
22pub fn camel_case(subject: &str) -> String {
23 camel_and_pascal_case(subject, TitleMode::Normal)
24}
25
26#[derive(Clone, Copy, PartialEq)]
27enum TitleMode {
28 Normal,
29 Caps,
30}
31
32fn camel_and_pascal_case(subject: &str, title_mode: TitleMode) -> String {
33 return match subject.len() {
34 0 => subject.to_string(),
35 _ => return_string(subject, title_mode),
36 };
37
38 fn return_string(subject: &str, title_mode: TitleMode) -> String {
39 let mut res = String::with_capacity(subject.len());
40 for (i, c) in crate::split::words(subject).iter().enumerate() {
41 let s = if i == 0 && title_mode == TitleMode::Normal {
42 lower_case(c)
43 } else {
44 capitalize(c, true)
45 };
46 res.push_str(&s);
47 }
48
49 res
50 }
51}
52
53/// Converts the first character of `subject` to upper case. If `restToLower` is `true`, convert the rest of `subject` to lower case.
54///
55/// # Arguments
56///
57/// * `subject` - The string to capitalize.
58/// * `rest_to_lower` - Convert the rest of `subject` to lower case.
59///
60/// # Example
61///
62/// ```
63/// use voca_rs::*;
64/// case::capitalize("green", true);
65/// // => "Green"
66/// case::capitalize("Say Hello to ME", true);
67/// // => "Say hello to me"
68/// use voca_rs::Voca;
69/// "green"._capitalize(true);
70/// // => "Green"
71/// ```
72pub fn capitalize(subject: &str, rest_to_lower: bool) -> String {
73 let rest_to_lower_mode = if rest_to_lower {
74 RestMode::Lower
75 } else {
76 RestMode::Normal
77 };
78 capitalize_decapitalize(subject, rest_to_lower_mode, CapsMode::Caps)
79}
80
81#[derive(Clone, Copy, PartialEq)]
82enum RestMode {
83 Lower,
84 Normal,
85}
86#[derive(Clone, Copy, PartialEq)]
87enum CapsMode {
88 Caps,
89 Small,
90}
91
92fn capitalize_decapitalize(subject: &str, rest_mode: RestMode, caps_mode: CapsMode) -> String {
93 return match subject.len() {
94 0 => subject.to_string(),
95 _ => return_string(subject, rest_mode, caps_mode),
96 };
97
98 fn return_string(subject: &str, rest_mode: RestMode, caps_mode: CapsMode) -> String {
99 let mut res = String::with_capacity(subject.len());
100
101 for (i, c) in crate::split::chars(subject).iter().enumerate() {
102 let s = if i == 0 {
103 match caps_mode {
104 CapsMode::Caps => c.to_uppercase(),
105 CapsMode::Small => c.to_lowercase(),
106 }
107 } else {
108 match rest_mode {
109 RestMode::Lower => c.to_lowercase(),
110 RestMode::Normal => (*c).to_string(),
111 }
112 };
113 res.push_str(&s);
114 }
115
116 res
117 }
118}
119/// Converts the first character of `subject` to lower case. If `restToLower` is `true`, convert the rest of `subject` to lower case.
120///
121/// # Arguments
122///
123/// * `subject` - The string to decapitalize.
124/// * `rest_to_lower` - Convert the rest of `subject` to lower case.
125/// # Example
126///
127/// ```
128/// use voca_rs::*;
129/// case::decapitalize("Green", true);
130/// // => "green"
131/// case::decapitalize("Say Hello to ME", false);
132/// // => "say Hello to ME"
133/// use voca_rs::Voca;
134/// "Green"._decapitalize(true);
135/// // => "green"
136/// ```
137pub fn decapitalize(subject: &str, rest_to_lower: bool) -> String {
138 let rest_to_lower_mode = if rest_to_lower {
139 RestMode::Lower
140 } else {
141 RestMode::Normal
142 };
143 capitalize_decapitalize(subject, rest_to_lower_mode, CapsMode::Small)
144}
145
146/// Converts the `subject` to kebab case.
147///
148/// # Arguments
149///
150/// * `subject` - The string to convert to kebab case.
151///
152/// # Example
153/// ```
154/// use voca_rs::*;
155/// case::kebab_case("goodbye blue sky");
156/// // => "goodbye-blue-sky"
157/// case::kebab_case("GoodbyeBlueSky");
158/// // => "goodbye-blue-sky"
159/// case::kebab_case("-Goodbye-Blue-Sky-");
160/// // => "goodbye-blue-sky"
161/// use voca_rs::Voca;
162/// "goodbye blue sky"._kebab_case();
163/// // => "goodbye-blue-sky"
164/// ```
165pub fn kebab_case(subject: &str) -> String {
166 kebab_and_shouty_kebab_and_train_case(subject, KebabMode::Normal)
167}
168
169/// Converts the `subject` to SHOUTY kebab case.
170///
171/// # Arguments
172///
173/// * `subject` - The string to convert to SHOUTY kebab case.
174///
175/// # Example
176/// ```
177/// use voca_rs::*;
178/// case::shouty_kebab_case("goodbye blue sky");
179/// // => "GOODBYE-BLUE-SKY"
180/// case::shouty_kebab_case("GoodbyeBlueSky");
181/// // => "GOODBYE-BLUE-SKY"
182/// case::shouty_kebab_case("-Goodbye-Blue-Sky-");
183/// // => "GOODBYE-BLUE-SKY"
184/// use voca_rs::Voca;
185/// "goodbye blue sky"._shouty_kebab_case();
186/// // => "GOODBYE-BLUE-SKY"
187/// ```
188pub fn shouty_kebab_case(subject: &str) -> String {
189 kebab_and_shouty_kebab_and_train_case(subject, KebabMode::Shouty)
190}
191
192#[derive(Clone, Copy, PartialEq)]
193enum KebabMode {
194 Normal,
195 Shouty,
196 Train,
197}
198
199fn kebab_and_shouty_kebab_and_train_case(subject: &str, kebab_mode: KebabMode) -> String {
200 match subject.len() {
201 0 => subject.to_string(),
202 _ => crate::split::words(subject)
203 .into_iter()
204 .map(|c| match kebab_mode {
205 KebabMode::Normal => lower_case(c),
206 KebabMode::Shouty => upper_case(c),
207 KebabMode::Train => capitalize(c, true),
208 })
209 .collect::<Vec<String>>()
210 .join("-"),
211 }
212}
213
214/// Converts the `subject` to lower case.
215///
216/// # Arguments
217///
218/// * `subject` - The string to convert to lower case.
219///
220/// # Example
221///
222/// ```
223/// use voca_rs::*;
224/// case::lower_case("Green");
225/// // => "green"
226/// case::lower_case("Say Hello to ME");
227/// // => "say hello to me"
228/// use voca_rs::Voca;
229/// "Green"._lower_case();
230/// // => "green"
231/// ```
232pub fn lower_case(subject: &str) -> String {
233 match subject.len() {
234 0 => subject.to_string(),
235 _ => {
236 let mut res = String::with_capacity(subject.len());
237 for c in crate::split::chars(subject).iter() {
238 res.push_str(&c.to_lowercase());
239 }
240 res
241 }
242 }
243}
244
245/// Converts the `subject` to pascal case.
246///
247/// # Arguments
248///
249/// * `subject` - The string to convert to pascal case.
250///
251/// # Example
252/// ```
253/// use voca_rs::*;
254/// case::pascal_case("bird flight");
255/// // => "BirdFlight"
256/// case::pascal_case("BirdFlight");
257/// // => "BirdFlight"
258/// case::pascal_case("-BIRD-FLIGHT-");
259/// // => "BirdFlight"
260/// use voca_rs::Voca;
261/// "bird flight"._pascal_case();
262/// // => "BirdFlight"
263/// ```
264pub fn pascal_case(subject: &str) -> String {
265 camel_and_pascal_case(subject, TitleMode::Caps)
266}
267
268/// Converts the `subject` to snake case.
269///
270/// # Arguments
271///
272/// * `subject` - The string to convert to snake case.
273///
274/// # Example
275/// ```
276/// use voca_rs::*;
277/// case::snake_case("learning to fly");
278/// // => "learning_to_fly"
279/// case::snake_case("LearningToFly");
280/// // => "learning_to_fly"
281/// case::snake_case("-Learning-To-Fly-");
282/// // => "learning_to_fly"
283/// use voca_rs::Voca;
284/// "learning to fly"._snake_case();
285/// // => "learning_to_fly"
286/// ```
287pub fn snake_case(subject: &str) -> String {
288 snake_and_shouty_snake_case(subject, false)
289}
290
291/// Converts the `subject` to SHOUTY snake case.
292///
293/// # Arguments
294///
295/// * `subject` - The string to convert to shouty snake case.
296///
297/// # Example
298/// ```
299/// use voca_rs::*;
300/// case::shouty_snake_case("learning to fly");
301/// // => "LEARNING_TO_FLY"
302/// case::shouty_snake_case("LearningToFly");
303/// // => "LEARNING_TO_FLY"
304/// case::shouty_snake_case("-Learning-To-Fly-");
305/// // => "LEARNING_TO_FLY"
306/// use voca_rs::Voca;
307/// "learning to fly"._shouty_snake_case();
308/// // => "LEARNING_TO_FLY"
309/// ```
310pub fn shouty_snake_case(subject: &str) -> String {
311 snake_and_shouty_snake_case(subject, true)
312}
313
314fn snake_and_shouty_snake_case(subject: &str, shouty: bool) -> String {
315 match subject.len() {
316 0 => subject.to_string(),
317 _ => crate::split::words(subject)
318 .into_iter()
319 .map(|c| {
320 if shouty {
321 upper_case(c)
322 } else {
323 lower_case(c)
324 }
325 })
326 .collect::<Vec<String>>()
327 .join("_"),
328 }
329}
330
331/// Converts the uppercase alpha characters of `subject` to lowercase and lowercase characters to uppercase.
332///
333/// # Arguments
334///
335/// * `subject` - The string to swap the case.
336///
337/// # Example
338/// ```
339/// use voca_rs::*;
340/// case::swap_case("League of Shadows");
341/// // => "lEAGUE OF sHADOWS"
342/// case::swap_case("2 üBer Bees");
343/// // => "2 ÜbER bEES"
344/// use voca_rs::Voca;
345/// "League of Shadows"._swap_case();
346/// // => "lEAGUE OF sHADOWS"
347/// ```
348pub fn swap_case(subject: &str) -> String {
349 match subject.len() {
350 0 => subject.to_string(),
351 _ => crate::split::chars(subject)
352 .into_iter()
353 .map(|s| {
354 s.chars()
355 .filter_map(|c| {
356 if c.is_lowercase() {
357 c.to_uppercase().next()
358 } else {
359 c.to_lowercase().next()
360 }
361 })
362 .collect()
363 })
364 .collect::<Vec<String>>()
365 .join(""),
366 }
367}
368
369/// Converts the `subject` to title case.
370///
371/// # Arguments
372///
373/// * `subject` - The string to convert to title case.
374///
375/// # Example
376/// ```
377/// use voca_rs::*;
378/// case::title_case("bird flight");
379/// // => "Bird Flight"
380/// case::title_case("BirdFlight");
381/// // => "Bird Flight"
382/// case::title_case("-BIRD-FLIGHT-");
383/// // => "Bird Flight"
384/// use voca_rs::Voca;
385/// "bird flight"._title_case();
386/// // => "Bird Flight"
387/// ```
388pub fn title_case(subject: &str) -> String {
389 match subject.len() {
390 0 => subject.to_string(),
391 _ => crate::split::words(subject)
392 .into_iter()
393 .map(|c| capitalize(c, true))
394 .collect::<Vec<String>>()
395 .join(" "),
396 }
397}
398
399/// Converts the `subject` to train case.
400///
401/// # Arguments
402///
403/// * `subject` - The string to convert to train case.
404///
405/// # Example
406/// ```
407/// use voca_rs::*;
408/// case::train_case("goodbye blue sky");
409/// // => "Goodbye-Blue-Sky"
410/// case::train_case("GoodbyeBlueSky");
411/// // => "Goodbye-Blue-Sky"
412/// case::train_case("-Goodbye-Blue-Sky-");
413/// // => "Goodbye-Blue-Sky"
414/// use voca_rs::Voca;
415/// "goodbye blue sky"._train_case();
416/// // => "Goodbye-Blue-Sky"
417/// ```
418pub fn train_case(subject: &str) -> String {
419 kebab_and_shouty_kebab_and_train_case(subject, KebabMode::Train)
420}
421
422/// Converts the `subject` to upper case.
423///
424/// # Arguments
425///
426/// * `subject` - The string to convert to upper case.
427///
428/// # Example
429///
430/// ```
431/// use voca_rs::*;
432/// case::upper_case("Green");
433/// // => "GREEN"
434/// case::upper_case("Say Hello to ME");
435/// // => "SAY HELLO TO ME"
436/// use voca_rs::Voca;
437/// "Green"._upper_case();
438/// // => "GREEN"
439/// ```
440pub fn upper_case(subject: &str) -> String {
441 match subject.len() {
442 0 => subject.to_string(),
443 _ => {
444 let mut res = String::with_capacity(subject.len());
445 for c in crate::split::chars(subject).iter() {
446 res.push_str(&c.to_uppercase());
447 }
448 res
449 }
450 }
451}
452
453/// Converts the first character of the `subject` to lower case.
454///
455/// # Arguments
456///
457/// * `subject` - The string to convert.
458///
459/// # Example
460///
461/// ```
462/// use voca_rs::*;
463/// case::lower_first("Fred");
464/// // => "fred"
465/// case::lower_first("FRED");
466/// // => "fRED"
467/// use voca_rs::Voca;
468/// "Fred"._lower_first();
469/// // => "fred"
470/// ```
471pub fn lower_first(subject: &str) -> String {
472 decapitalize(subject, false)
473}
474
475/// Converts the first character of the `subject` to upper case.
476///
477/// # Arguments
478///
479/// * `subject` - The string to convert.
480///
481/// # Example
482///
483/// ```
484/// use voca_rs::*;
485/// case::upper_first("fred");
486/// // => "Fred"
487/// case::upper_first("FRED");
488/// // => "FRED"
489/// use voca_rs::Voca;
490/// "fred"._upper_first();
491/// // => "Fred"
492/// ```
493pub fn upper_first(subject: &str) -> String {
494 capitalize(subject, false)
495}