From ee1e3550d0d1d7f2bb013f4a8851e76eb484141c Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Thu, 11 Jan 2018 14:48:43 +0800 Subject: [PATCH] support response references --- Sources/Swagger/Reference.swift | 14 +++++++ Sources/Swagger/SwaggerSpec.swift | 37 +++++++++++-------- .../Sources/TestSpec/Requests/GetString.swift | 26 +++++++++++++ Specs/TestSpec/spec.yml | 7 ++++ 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/Sources/Swagger/Reference.swift b/Sources/Swagger/Reference.swift index d13f56721..36d060103 100644 --- a/Sources/Swagger/Reference.swift +++ b/Sources/Swagger/Reference.swift @@ -31,6 +31,20 @@ public class Reference { func resolve(with value: T) { _value = value } + + func getReferenceComponent(index: Int) -> String? { + let components = string.components(separatedBy: "/") + guard components.count > index else { return nil } + return components[index] + } + + public var referenceType: String? { + return getReferenceComponent(index: 1) + } + + public var referenceName: String? { + return getReferenceComponent(index: 2) + } } public enum PossibleReference: JSONObjectConvertible { diff --git a/Sources/Swagger/SwaggerSpec.swift b/Sources/Swagger/SwaggerSpec.swift index ef6c81d90..c0f4fdee6 100644 --- a/Sources/Swagger/SwaggerSpec.swift +++ b/Sources/Swagger/SwaggerSpec.swift @@ -122,28 +122,32 @@ extension SwaggerSpec: JSONObjectConvertible { func resolveReferences() { - func resolveDefinitionReference(_ reference: Reference) { - let components = reference.string.components(separatedBy: "/") - if components.count == 3 && components[0] == "#" && components[1] == "definitions" { - let name = components[2] - if let schema = definitions.first(where: { $0.name == name }) { - reference.resolve(with: schema.value) - } + func resolvePossibleReference(_ reference: PossibleReference, objects: [SwaggerObject], type: String) { + if case let .reference(reference) = reference { + resolveReference(reference, objects: objects, type: type) } } - func resolveParameterReference(_ reference: PossibleReference) { - if case let .reference(reference) = reference { - let components = reference.string.components(separatedBy: "/") - if components.count == 3 && components[0] == "#" && components[1] == "parameters" { - let name = components[2] - if let param = parameters.first(where: { $0.name == name }) { - reference.resolve(with: param.value) - } - } + func resolveReference(_ reference: Reference, objects: [SwaggerObject], type: String) { + if reference.referenceType == type, + let name = reference.referenceName, + let object = objects.first(where: { $0.name == name }) { + reference.resolve(with: object.value) } } + func resolveDefinitionReference(_ reference: Reference) { + resolveReference(reference, objects: definitions, type: "definitions") + } + + func resolveParameterReference(_ reference: PossibleReference) { + resolvePossibleReference(reference, objects: parameters, type: "parameters") + } + + func resolveResponseReference(_ reference: PossibleReference) { + resolvePossibleReference(reference, objects: responses, type: "responses") + } + func resolveSchema(_ schema: Schema) { switch schema.type { case let .reference(reference): resolveDefinitionReference(reference) @@ -179,6 +183,7 @@ extension SwaggerSpec: JSONObjectConvertible { path.operations.forEach { $0.pathParameters.forEach(resolveParameterReference) $0.operationParameters.forEach(resolveParameterReference) + $0.responses.map{$0.response}.forEach(resolveResponseReference) } } } diff --git a/Specs/TestSpec/generated/Swift/Sources/TestSpec/Requests/GetString.swift b/Specs/TestSpec/generated/Swift/Sources/TestSpec/Requests/GetString.swift index 387cba761..925de031d 100644 --- a/Specs/TestSpec/generated/Swift/Sources/TestSpec/Requests/GetString.swift +++ b/Specs/TestSpec/generated/Swift/Sources/TestSpec/Requests/GetString.swift @@ -26,33 +26,59 @@ extension TestSpec { /** string response */ case status200(String) + /** 400 response */ + case status400(String) + public var success: String? { switch self { case .status200(let response): return response + default: return nil + } + } + + public var failure: String? { + switch self { + case .status400(let response): return response + default: return nil + } + } + + /// either success or failure value. Success is anything in the 200..<300 status code range + public var responseResult: APIResponseResult { + if let successValue = success { + return .success(successValue) + } else if let failureValue = failure { + return .failure(failureValue) + } else { + fatalError("Response does not have success or failure response") } } public var response: Any { switch self { case .status200(let response): return response + case .status400(let response): return response } } public var statusCode: Int { switch self { case .status200: return 200 + case .status400: return 400 } } public var successful: Bool { switch self { case .status200: return true + case .status400: return false } } public init(statusCode: Int, data: Data) throws { switch statusCode { case 200: self = try .status200(JSONDecoder.decode(data: data)) + case 400: self = try .status400(JSONDecoder.decode(data: data)) default: throw APIError.unexpectedStatusCode(statusCode: statusCode, data: data) } } diff --git a/Specs/TestSpec/spec.yml b/Specs/TestSpec/spec.yml index 74967854c..e7c1d3841 100644 --- a/Specs/TestSpec/spec.yml +++ b/Specs/TestSpec/spec.yml @@ -70,6 +70,8 @@ paths: description: string response schema: type: string + 400: + $ref: '#/responses/400' definitions: User: type: object @@ -105,3 +107,8 @@ definitions: description: definition with only additional properties type: object additionalProperties: true +responses: + 400: + description: 400 response + schema: + type: string