7
7
8
8
import Foundation
9
9
10
- public extension String {
11
-
12
- public enum CaseFormat {
10
+ public enum StringCaseFormat {
13
11
14
- public enum SnakeCase {
15
- case lower
16
- case upper
17
- case capitalized
18
- }
12
+ public enum SnakeCase {
13
+ case lower
14
+ case upper
15
+ case capitalized
16
+ }
19
17
20
- public enum CamelCase {
21
- case `default`
22
- case capitalized
23
- }
18
+ public enum CamelCase {
19
+ case `default`
20
+ case capitalized
24
21
}
22
+ }
25
23
26
- public func snakeCased( _ format: CaseFormat . SnakeCase = . lower) -> String {
24
+ public extension String {
25
+
26
+ public func caseSplit( ) -> [ String ] {
27
+ var res : [ String ] = [ ]
28
+ let trim = self . trimmingCharacters ( in: CharacterSet . whitespacesAndNewlines)
27
29
let alphanumerics = CharacterSet . alphanumerics
28
30
let uppercaseLetters = CharacterSet . uppercaseLetters
29
31
let lowercaseLetters = CharacterSet . lowercaseLetters
30
- var underscore = false
31
- var previousCase = 0 // 0 none, 1 upper, 2 lower, 3 other
32
- var currentCase = 0 // 0 none, 1 upper, 2 lower, 3 other
33
- var letterInWord = 0
34
- var res = " "
35
- for ch in self . trimmingCharacters ( in: CharacterSet . whitespacesAndNewlines) {
36
- for scalar in ch. unicodeScalars {
32
+ trim. split ( separator: " " ) . forEach { str in
33
+ var previousCase = 0
34
+ var currentCase = 0
35
+ var caseChange = false
36
+ var scalars = UnicodeScalarView ( )
37
+ for scalar in str. unicodeScalars {
37
38
if alphanumerics. contains ( scalar) {
38
39
if uppercaseLetters. contains ( scalar) {
39
40
currentCase = 1
@@ -42,8 +43,7 @@ public extension String {
42
43
} else {
43
44
currentCase = 0
44
45
}
45
- var str = String ( scalar)
46
- var caseChange = underscore
46
+ let letterInWord = scalars. count
47
47
if !caseChange && letterInWord > 0 {
48
48
if currentCase != previousCase {
49
49
if previousCase == 1 {
@@ -56,57 +56,42 @@ public extension String {
56
56
}
57
57
}
58
58
if caseChange {
59
- res += " _ "
60
- letterInWord = 0
61
- }
62
- letterInWord += 1
63
- if format == . capitalized {
64
- if currentCase != 1 {
65
- if caseChange || previousCase == 0 {
66
- str = str. uppercased ( )
67
- }
68
- } else if !caseChange {
69
- str = str. lowercased ( )
70
- }
71
- } else if format == . upper && currentCase != 1 {
72
- str = str. uppercased ( )
73
- } else if format == . lower && currentCase != 2 {
74
- str = str. lowercased ( )
59
+ res. append ( String ( scalars) )
60
+ scalars. removeAll ( )
75
61
}
76
- res += str
77
- underscore = false ;
78
- previousCase = currentCase;
62
+ scalars . append ( scalar )
63
+ caseChange = false
64
+ previousCase = currentCase
79
65
} else {
80
- underscore = true
66
+ caseChange = true
81
67
}
82
68
}
69
+ if scalars. count > 0 {
70
+ res. append ( String ( scalars) )
71
+ }
83
72
}
84
73
return res
85
74
}
86
75
87
- public func camelCased( _ format: CaseFormat . CamelCase = . default) -> String {
88
- var uppercase = format == . capitalized;
89
- var res = " "
90
- let alphanumerics = CharacterSet . alphanumerics
91
- let lowercaseLetters = CharacterSet . lowercaseLetters
92
- for ch in self . trimmingCharacters ( in: CharacterSet . whitespacesAndNewlines) {
93
- for scalar in ch. unicodeScalars {
94
- if alphanumerics. contains ( scalar) {
95
- var str = String ( scalar)
96
- if uppercase {
97
- if lowercaseLetters. contains ( scalar) {
98
- str = str. uppercased ( )
99
- }
100
- uppercase = false
101
- } else if res. count == 0 {
102
- str = str. lowercased ( )
103
- }
104
- res += str
105
- } else {
106
- uppercase = true
107
- }
76
+ public func snakeCased( _ format: StringCaseFormat . SnakeCase = . lower) -> String {
77
+ let split = self . caseSplit ( )
78
+ if format == . lower {
79
+ return split. map { $0. lowercased ( ) } . joined ( separator: " _ " )
80
+ } else if format == . upper {
81
+ return split. map { $0. uppercased ( ) } . joined ( separator: " _ " )
82
+ }
83
+ return split. map { $0. capitalized } . joined ( separator: " _ " )
84
+ }
85
+
86
+ public func camelCased( _ format: StringCaseFormat . CamelCase = . default) -> String {
87
+ var res : [ String ] = [ ]
88
+ for (i, str) in self . caseSplit ( ) . enumerated ( ) {
89
+ if i == 0 && format == . default {
90
+ res. append ( str. lowercased ( ) )
91
+ continue
108
92
}
93
+ res. append ( str. capitalized)
109
94
}
110
- return res
95
+ return res. joined ( )
111
96
}
112
97
}
0 commit comments