12
12
//
13
13
//===----------------------------------------------------------------------===//
14
14
import OpenAPIKit
15
+ import Foundation
15
16
16
17
/// A wrapper of an OpenAPI operation that includes the information
17
18
/// about the parent containers of the operation, such as its path
@@ -244,6 +245,11 @@ extension OperationDescription {
244
245
)
245
246
}
246
247
248
+ /// The regular expression for parsing subcomponents of path components.
249
+ ///
250
+ /// Either a parameter `{foo}` or a constant value `foo`.
251
+ private static let pathParameterRegex = try ! NSRegularExpression ( pattern: #"(\{[a-zA-Z0-9_]+\})|([^{}]+)"# )
252
+
247
253
/// Returns a string that contains the template to be generated for
248
254
/// the client that fills in path parameters, and an array expression
249
255
/// with the parameter values.
@@ -257,19 +263,35 @@ extension OperationDescription {
257
263
// in which the parameters are used.
258
264
var newComponents : [ String ] = [ ]
259
265
for component in path. components {
260
- guard component. hasPrefix ( " { " ) && component. hasSuffix ( " } " ) else {
261
- newComponents. append ( component)
262
- continue
263
- }
264
- let componentName = String ( component. dropFirst ( ) . dropLast ( ) )
265
- guard pathParameterNames. contains ( componentName) else {
266
- throw GenericError (
267
- message:
268
- " Parameter ' \( componentName) ' used in the path ' \( self . path. rawValue) ', but not found in the defined list of path parameters. "
269
- )
266
+ let matches = Self . pathParameterRegex. matches (
267
+ in: component,
268
+ options: [ ] ,
269
+ range: NSRange ( location: 0 , length: component. utf16. count)
270
+ )
271
+ var subcomponents : [ String ] = [ ]
272
+ for match in matches {
273
+ for i in 1 ..< match. numberOfRanges {
274
+ let range = match. range ( at: i)
275
+ guard range. location != NSNotFound, let swiftRange = Range ( range, in: component) else {
276
+ continue
277
+ }
278
+ let value = component [ swiftRange]
279
+ if value. hasPrefix ( " { " ) && value. hasSuffix ( " } " ) {
280
+ let componentName = String ( value. dropFirst ( ) . dropLast ( ) )
281
+ guard pathParameterNames. contains ( componentName) else {
282
+ throw GenericError (
283
+ message:
284
+ " Parameter ' \( componentName) ' used in the path ' \( self . path. rawValue) ', but not found in the defined list of path parameters. "
285
+ )
286
+ }
287
+ orderedPathParameters. append ( componentName)
288
+ subcomponents. append ( " {} " )
289
+ } else {
290
+ subcomponents. append ( String ( value) )
291
+ }
292
+ }
270
293
}
271
- orderedPathParameters. append ( componentName)
272
- newComponents. append ( " {} " )
294
+ newComponents. append ( subcomponents. joined ( ) )
273
295
}
274
296
let newPath = OpenAPI . Path ( newComponents, trailingSlash: path. trailingSlash)
275
297
let names : [ Expression ] = orderedPathParameters. map { param in
0 commit comments