Skip to content

Commit 14b090a

Browse files
committed
Update the implementation with the latest feedback on the proposal
1 parent bda0eb3 commit 14b090a

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/SwiftSafeNames.swift

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,15 @@ extension String {
9797

9898
// 1. Leave leading underscores as-are
9999
// 2. In the middle: word separators: ["_", "-", <space>] -> remove and capitalize next word
100-
// 3. In the middle: period: ["."] -> replace with "_"
100+
// 3. In the middle: period: [".", "/"] -> replace with "_"
101+
// 4. In the middle: drop ["{", "}"] -> replace with ""
101102

102103
var buffer: [Character] = []
103104
buffer.reserveCapacity(count)
104105

105106
enum State {
106107
case modifying
108+
case fallback
107109
case preFirstWord
108110
case accumulatingWord
109111
case waitingForWordStarter
@@ -129,7 +131,7 @@ extension String {
129131
state = .accumulatingWord
130132
} else {
131133
// Illegal character, fall back to the defensive strategy.
132-
return safeForSwiftCode_defensive(options: options)
134+
state = .fallback
133135
}
134136
case .accumulatingWord:
135137
if char.isLetter || char.isNumber {
@@ -139,22 +141,25 @@ extension String {
139141
buffer.append(char)
140142
}
141143
state = .accumulatingWord
142-
} else if char == "_" || char == "-" || char == " " {
144+
} else if ["_", "-", " "].contains(char) {
143145
// In the middle of an identifier, dashes, underscores, and spaces are considered
144146
// word separators, so we remove the character and end the current word.
145147
state = .waitingForWordStarter
146-
} else if char == "." {
147-
// In the middle of an identifier, a period gets replaced with an underscore, but continues
148-
// the current word.
148+
} else if [".", "/"].contains(char) {
149+
// In the middle of an identifier, a period or a slash gets replaced with
150+
// an underscore, but continues the current word.
149151
buffer.append("_")
150152
state = .accumulatingWord
153+
} else if ["{", "}"].contains(char) {
154+
// In the middle of an identifier, curly braces are dropped.
155+
state = .accumulatingWord
151156
} else {
152157
// Illegal character, fall back to the defensive strategy.
153-
return safeForSwiftCode_defensive(options: options)
158+
state = .fallback
154159
}
155160
case .waitingForWordStarter:
156-
if char == "_" || char == "-" {
157-
// Between words, just drop dashes, underscores, and spaces, since
161+
if ["_", "-", ".", "/", "{", "}"].contains(char) {
162+
// Between words, just drop allowed special characters, since
158163
// we're already between words anyway.
159164
state = .waitingForWordStarter
160165
} else if char.isLetter || char.isNumber {
@@ -163,12 +168,15 @@ extension String {
163168
state = .accumulatingWord
164169
} else {
165170
// Illegal character, fall back to the defensive strategy.
166-
return safeForSwiftCode_defensive(options: options)
171+
state = .fallback
167172
}
168-
case .modifying:
173+
case .modifying, .fallback:
169174
preconditionFailure("Logic error in \(#function), string: '\(self)'")
170175
}
171176
precondition(state != .modifying, "Logic error in \(#function), string: '\(self)'")
177+
if case .fallback = state {
178+
return safeForSwiftCode_defensive(options: options)
179+
}
172180
}
173181
if buffer.isEmpty || state == .preFirstWord {
174182
return safeForSwiftCode_defensive(options: options)

Tests/OpenAPIGeneratorCoreTests/Extensions/Test_SwiftSafeNames.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,23 @@ final class Test_SwiftSafeNames: Test_Core {
3939
// Numbers
4040
("version 2.0", "version_space_2_period_0", "Version2_0", "version2_0"),
4141
("V1.2Release", "V1_period_2Release", "V1_2Release", "v1_2Release"),
42-
42+
4343
// Synthesized operationId from method + path
4444
(
4545
"get/pets/{petId}/notifications",
4646
"get_sol_pets_sol__lcub_petId_rcub__sol_notifications",
47-
"GetPetsPetIdNotifications",
48-
"getPetsPetIdNotifications"
47+
"Get_pets_petId_notifications",
48+
"get_pets_petId_notifications",
4949
),
50-
50+
(
51+
"get/name/v{version}.zip",
52+
"get_sol_name_sol_v_lcub_version_rcub__period_zip",
53+
"Get_name_vversion_zip",
54+
"get_name_vversion_zip"
55+
),
56+
5157
// Technical strings
52-
("file/path/to/resource", "file_sol_path_sol_to_sol_resource", "file_sol_path_sol_to_sol_resource", "file_sol_path_sol_to_sol_resource"),
58+
("file/path/to/resource", "file_sol_path_sol_to_sol_resource", "File_path_to_resource", "file_path_to_resource"),
5359
("[email protected]", "user_period_name_commat_domain_period_com", "user_period_name_commat_domain_period_com", "user_period_name_commat_domain_period_com"),
5460
("hello.world.2023", "hello_period_world_period_2023", "Hello_world_2023", "hello_world_2023"),
5561
("order#123", "order_num_123", "order_num_123", "order_num_123"),

0 commit comments

Comments
 (0)