Skip to content

Commit 4991b7e

Browse files
authored
Merge pull request #379 from mattpolzin/bugfix/378/content-types
Add support for multiple content types on one content encoding object
2 parents ea46a4c + ce799a3 commit 4991b7e

File tree

5 files changed

+73
-35
lines changed

5 files changed

+73
-35
lines changed

.github/workflows/codecov.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
image: swift:5.8
99
runs-on: ubuntu-latest
1010
steps:
11-
- uses: actions/checkout@v3
11+
- uses: actions/checkout@v4
1212
- run: swift test --enable-test-discovery --enable-code-coverage
1313
- id: analysis
1414
uses: mattpolzin/swift-codecov-action@0.7.5

.github/workflows/documentation.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13-
- uses: actions/checkout@v3
13+
- uses: actions/checkout@v4
1414
# TODO: replace the documentation generator with something that is still maintained.
1515

1616
# - name: Generate Documentation

.github/workflows/tests.yml

+4-28
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,15 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
image:
16-
- swift:5.1-xenial
17-
- swift:5.1-bionic
18-
- swift:5.2-xenial
19-
- swift:5.2-bionic
2016
- swift:5.2-focal
2117
- swift:5.2-centos8
22-
- swift:5.2-amazonlinux2
23-
- swift:5.3-xenial
24-
- swift:5.3-bionic
2518
- swift:5.3-focal
2619
- swift:5.3-centos8
27-
- swift:5.3-amazonlinux2
2820
# see below for 5.4, 5.5, etc.
2921
container: ${{ matrix.image }}
3022
steps:
3123
- name: Checkout code
32-
uses: actions/checkout@v3
24+
uses: actions/checkout@v4
3325
- name: Run tests
3426
run: swift test --enable-test-discovery
3527
# 5.4 is separate because there was a bug in the compiler that caused
@@ -40,15 +32,12 @@ jobs:
4032
fail-fast: false
4133
matrix:
4234
image:
43-
- swift:5.4-xenial
44-
- swift:5.4-bionic
4535
- swift:5.4-focal
4636
- swift:5.4-centos8
47-
- swift:5.4-amazonlinux2
4837
container: ${{ matrix.image }}
4938
steps:
5039
- name: Checkout code
51-
uses: actions/checkout@v3
40+
uses: actions/checkout@v4
5241
- name: Run tests (without test discovery flag)
5342
run: swift test -Xswiftc -Xfrontend -Xswiftc -sil-verify-none
5443
linux-5_5-plus:
@@ -57,36 +46,23 @@ jobs:
5746
fail-fast: false
5847
matrix:
5948
image:
60-
- swift:5.5-xenial
61-
- swift:5.5-bionic
6249
- swift:5.5-focal
6350
- swift:5.5-centos8
64-
- swift:5.5-amazonlinux2
65-
- swift:5.6-bionic
6651
- swift:5.6-focal
67-
- swift:5.6-amazonlinux2
68-
- swift:5.7-bionic
6952
- swift:5.7-focal
7053
- swift:5.7-jammy
71-
- swift:5.7-amazonlinux2
72-
- swift:5.8-bionic
7354
- swift:5.8-focal
7455
- swift:5.8-jammy
75-
- swift:5.8-amazonlinux2
7656
- swift:5.9-focal
7757
- swift:5.9-jammy
78-
- swift:5.9-amazonlinux2
7958
- swift:5.10-focal
8059
- swift:5.10-jammy
81-
- swift:5.10-amazonlinux2
82-
- swiftlang/swift:nightly-bionic
8360
- swiftlang/swift:nightly-focal
8461
- swiftlang/swift:nightly-jammy
85-
- swiftlang/swift:nightly-amazonlinux2
8662
container: ${{ matrix.image }}
8763
steps:
8864
- name: Checkout code
89-
uses: actions/checkout@v3
65+
uses: actions/checkout@v4
9066
- name: Run tests
9167
run: swift test
9268
osx:
@@ -97,6 +73,6 @@ jobs:
9773
with:
9874
xcode-version: latest
9975
- name: Checkout code
100-
uses: actions/checkout@v3
76+
uses: actions/checkout@v4
10177
- name: Run tests
10278
run: swift test --enable-test-discovery

Sources/OpenAPIKit/Content/ContentEncoding.swift

+40-5
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,54 @@ extension OpenAPI.Content {
1414
public struct Encoding: Equatable {
1515
public typealias Style = OpenAPI.Parameter.SchemaContext.Style
1616

17-
public let contentType: OpenAPI.ContentType?
17+
/// If an encoding object only contains 1 content type, it will be populated here.
18+
/// Two or more content types will result in a null value here but the `contentTypes`
19+
/// (plural) property will contain all content types specified.
20+
///
21+
/// The singular `contentType` property is only provided for backwards compatibility and
22+
/// using the plural `contentTypes` property should be preferred.
23+
@available(*, deprecated, message: "use contentTypes instead")
24+
public var contentType: OpenAPI.ContentType? {
25+
guard let contentType = contentTypes.first,
26+
contentTypes.count == 1 else {
27+
return nil
28+
}
29+
return contentType
30+
}
31+
32+
public let contentTypes: [OpenAPI.ContentType]
1833
public let headers: OpenAPI.Header.Map?
1934
public let style: Style
2035
public let explode: Bool
2136
public let allowReserved: Bool
2237

38+
/// The singular `contentType` argument is only provided for backwards compatibility and
39+
/// using the plural `contentTypes` argument should be preferred.
2340
public init(
2441
contentType: OpenAPI.ContentType? = nil,
42+
contentTypes: [OpenAPI.ContentType] = [],
2543
headers: OpenAPI.Header.Map? = nil,
2644
style: Style = Self.defaultStyle,
2745
allowReserved: Bool = false
2846
) {
29-
self.contentType = contentType
47+
self.contentTypes = contentTypes + [contentType].compactMap { $0 }
3048
self.headers = headers
3149
self.style = style
3250
self.explode = style.defaultExplode
3351
self.allowReserved = allowReserved
3452
}
3553

54+
/// The singular `contentType` argument is only provided for backwards compatibility and
55+
/// using the plural `contentTypes` argument should be preferred.
3656
public init(
3757
contentType: OpenAPI.ContentType? = nil,
58+
contentTypes: [OpenAPI.ContentType] = [],
3859
headers: OpenAPI.Header.Map? = nil,
3960
style: Style = Self.defaultStyle,
4061
explode: Bool,
4162
allowReserved: Bool = false
4263
) {
43-
self.contentType = contentType
64+
self.contentTypes = contentTypes + [contentType].compactMap { $0 }
4465
self.headers = headers
4566
self.style = style
4667
self.explode = explode
@@ -56,7 +77,12 @@ extension OpenAPI.Content.Encoding: Encodable {
5677
public func encode(to encoder: Encoder) throws {
5778
var container = encoder.container(keyedBy: CodingKeys.self)
5879

59-
try container.encodeIfPresent(contentType, forKey: .contentType)
80+
if contentTypes.count > 0 {
81+
let contentTypesString = contentTypes
82+
.map(\.rawValue)
83+
.joined(separator: ", ")
84+
try container.encode(contentTypesString, forKey: .contentType)
85+
}
6086
try container.encodeIfPresent(headers, forKey: .headers)
6187

6288
if style != Self.defaultStyle {
@@ -77,7 +103,16 @@ extension OpenAPI.Content.Encoding: Decodable {
77103
public init(from decoder: Decoder) throws {
78104
let container = try decoder.container(keyedBy: CodingKeys.self)
79105

80-
contentType = try container.decodeIfPresent(OpenAPI.ContentType.self, forKey: .contentType)
106+
let contentTypesString = try container.decodeIfPresent(String.self, forKey: .contentType)
107+
if let contentTypesString = contentTypesString {
108+
contentTypes = contentTypesString
109+
.split(separator: ",")
110+
.compactMap { string in
111+
OpenAPI.ContentType.init(rawValue: string.trimmingCharacters(in: .whitespaces))
112+
}
113+
} else {
114+
contentTypes = []
115+
}
81116

82117
headers = try container.decodeIfPresent(OpenAPI.Header.Map.self, forKey: .headers)
83118

Tests/OpenAPIKitTests/Content/ContentTests.swift

+27
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,33 @@ extension ContentTests {
570570
XCTAssertEqual(encoding, OpenAPI.Content.Encoding(contentType: .csv))
571571
}
572572

573+
func test_encoding_multiple_contentTypes_encode() throws {
574+
let encoding = OpenAPI.Content.Encoding(contentTypes: [.csv, .json])
575+
576+
let encodedEncoding = try! orderUnstableTestStringFromEncoding(of: encoding)
577+
578+
assertJSONEquivalent(
579+
encodedEncoding,
580+
"""
581+
{
582+
"contentType" : "text\\/csv, application\\/json"
583+
}
584+
"""
585+
)
586+
}
587+
588+
func test_encoding_multiple_contentTypes_decode() throws {
589+
let encodingData =
590+
"""
591+
{
592+
"contentType": "text/csv, application/json"
593+
}
594+
""".data(using: .utf8)!
595+
let encoding = try! orderUnstableDecode(OpenAPI.Content.Encoding.self, from: encodingData)
596+
597+
XCTAssertEqual(encoding, OpenAPI.Content.Encoding(contentTypes: [.csv, .json]))
598+
}
599+
573600
func test_encoding_headers_encode() throws {
574601
let encoding = OpenAPI.Content.Encoding(headers: [
575602
"X-CustomThing": .init(OpenAPI.Header(schema: .string))

0 commit comments

Comments
 (0)