Skip to content

Commit

Permalink
✨ Add support for references in query element arrays (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
MadsBogeskov authored Nov 21, 2024
1 parent a973b51 commit c7f09dd
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 11 deletions.
4 changes: 3 additions & 1 deletion Sources/SwaggerSwiftML/Models/Operation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public struct Operation: Decodable {
} else if let parameter = try? parameterContainer.decode(Parameter.self) {
params.append(.node(parameter))
} else {
fatalError("Unknown object")
throw UnknownObject()
}
}
self.parameters = params
Expand All @@ -84,3 +84,5 @@ public struct Operation: Decodable {
// self.security = try con.decodeIfPresent(SecurityRequirement.self, forKey: .security)
}
}

struct UnknownObject: Error { }
55 changes: 46 additions & 9 deletions Sources/SwaggerSwiftML/Models/Parameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,57 @@ public struct Parameter: Decodable {
case "array":
let uniqueItems = try container.decodeIfPresent(Bool.self, forKey: .uniqueItems)
let collectionFormat = (try container.decodeIfPresent(CollectionFormat.self, forKey: .collectionFormat)) ?? .csv
let items = try container.decode(Items.self, forKey: .items)
type = .array(items, collectionFormat: collectionFormat, maxItems: maxItems, minItems: minItems, uniqueItems: uniqueItems ?? false)

if let items = try? container.decode(Items.self, forKey: .items) {
type = .array(
.node(items),
collectionFormat: collectionFormat,
maxItems: maxItems,
minItems: minItems,
uniqueItems: uniqueItems ?? false
)
} else if let reference = try? container.decode(Reference.self, forKey: .items) {
type = .array(
.reference(reference.ref),
collectionFormat: collectionFormat,
maxItems: maxItems,
minItems: minItems,
uniqueItems: uniqueItems ?? false
)
} else {
throw InvalidArrayType()
}

case "boolean":
type = .boolean
case "file":
type = .file
case "integer":
type = .integer(format: format, maximum: maximum, exclusiveMaximum: exclusiveMaximum, minimum: minimum, exclusiveMinimum: exclusiveMinimum, multipleOf: multipleOf)
type = .integer(
format: format,
maximum: maximum,
exclusiveMaximum: exclusiveMaximum,
minimum: minimum,
exclusiveMinimum: exclusiveMinimum,
multipleOf: multipleOf
)
case "number":
type = .number(format: format, maximum: maximum, exclusiveMaximum: exclusiveMaximum, minimum: minimum, exclusiveMinimum: exclusiveMinimum, multipleOf: multipleOf)
type = .number(
format: format,
maximum: maximum,
exclusiveMaximum: exclusiveMaximum,
minimum: minimum,
exclusiveMinimum: exclusiveMinimum,
multipleOf: multipleOf
)
case "string":
type = .string(format: format,
enumValues: enumeration,
maxLength: maxLength,
minLength: minLength,
pattern: pattern)
type = .string(
format: format,
enumValues: enumeration,
maxLength: maxLength,
minLength: minLength,
pattern: pattern
)
default:
type = nil
}
Expand Down Expand Up @@ -107,3 +142,5 @@ public struct Parameter: Decodable {
}
}
}

struct InvalidArrayType: Error { }
2 changes: 1 addition & 1 deletion Sources/SwaggerSwiftML/Models/ParameterType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ public indirect enum ParameterType {
case number(format: DataFormat?, maximum: Int?, exclusiveMaximum: Bool?, minimum: Int?, exclusiveMinimum: Bool?, multipleOf: Int?)
case integer(format: DataFormat?, maximum: Int?, exclusiveMaximum: Bool?, minimum: Int?, exclusiveMinimum: Bool?, multipleOf: Int?)
case boolean
case array(Items, collectionFormat: CollectionFormat, maxItems: Int?, minItems: Int?, uniqueItems: Bool)
case array(Node<Items>, collectionFormat: CollectionFormat, maxItems: Int?, minItems: Int?, uniqueItems: Bool)
case file
}
2 changes: 2 additions & 0 deletions Sources/SwaggerSwiftML/Models/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public struct Schema: Decodable {
if typeString == nil {
if container.contains(.properties) || container.contains(.allOf) {
typeString = "object"
} else if container.contains(.items) {
typeString = "array"
} else {
throw SwaggerError.failedToParse(description: "Failed to parse type without type information. The type has no properties or allOf defined and so it cant be an object. The object has these properties: \(container.allKeys.map { $0.rawValue }.joined(separator: ", "))", codingPath: container.codingPath)
}
Expand Down
6 changes: 6 additions & 0 deletions Tests/SwaggerSwiftMLTests/Parameter/array_with_ref.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
in: query
name: paramName
required: true
type: array
items:
$ref: "#/definitions/SomeType"
1 change: 1 addition & 0 deletions Tests/SwaggerSwiftMLTests/Parameter/formdata_param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ name: avatar
in: formData
required: true
type: file

10 changes: 10 additions & 0 deletions Tests/SwaggerSwiftMLTests/ParameterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,14 @@ final class ParameterTests: XCTestCase {

// XCTAssertEqual(parameter.location, .body)
}

func testArrayWithRef() {
let basicFileUrl = Bundle.module.url(forResource: "Parameter/array_with_ref", withExtension: "yaml")

let fileContents = try! String(contentsOf: basicFileUrl!, encoding: .utf8)

_ = try! YAMLDecoder().decode(Parameter.self, from: fileContents)

// XCTAssertEqual(parameter.location, .body)
}
}

0 comments on commit c7f09dd

Please sign in to comment.