Skip to content

Commit 104e5e1

Browse files
authored
Merge pull request #2 from mattpolzin/bugfix/omitting-null-values
Bugfix/omitting null values
2 parents 43786c1 + 8328309 commit 104e5e1

28 files changed

+723
-154
lines changed

Sources/OpenAPIKit/Content.swift

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,39 @@ extension OpenAPI.Content {
118118
}
119119

120120
extension OpenAPI.Content {
121-
public struct Encoding: Codable, Equatable {
121+
public struct Encoding: Equatable {
122+
public typealias Style = OpenAPI.PathItem.Parameter.Schema.Style
123+
122124
public let contentType: OpenAPI.ContentType?
123125
public let headers: OpenAPI.Header.Map?
124-
// public let style: String?
125-
// public let explode: Bool (defaults for this need to be tied to style making style a good candidate for abstraction)
126+
public let style: Style
127+
public let explode: Bool
126128
public let allowReserved: Bool
127129

128130
public init(contentType: OpenAPI.ContentType? = nil,
129131
headers: OpenAPI.Header.Map? = nil,
132+
style: Style = Self.defaultStyle,
133+
allowReserved: Bool = false) {
134+
self.contentType = contentType
135+
self.headers = headers
136+
self.style = style
137+
self.explode = style.defaultExplode
138+
self.allowReserved = allowReserved
139+
}
140+
141+
public init(contentType: OpenAPI.ContentType? = nil,
142+
headers: OpenAPI.Header.Map? = nil,
143+
style: Style = Self.defaultStyle,
144+
explode: Bool,
130145
allowReserved: Bool = false) {
131146
self.contentType = contentType
132147
self.headers = headers
148+
self.style = style
149+
self.explode = explode
133150
self.allowReserved = allowReserved
134151
}
152+
153+
public static let defaultStyle: Style = .default(for: .query)
135154
}
136155
}
137156

@@ -160,16 +179,9 @@ extension OpenAPI.Content: Encodable {
160179
try container.encode(example, forKey: .example)
161180
}
162181

163-
if encoding != nil {
164-
try container.encode(encoding, forKey: .encoding)
165-
}
182+
try encoding.encodeIfNotNil(to: &container, forKey: .encoding)
166183

167-
if vendorExtensions != [:] {
168-
for (key, value) in vendorExtensions {
169-
let xKey = key.starts(with: "x-") ? key : "x-\(key)"
170-
try container.encode(value, forKey: .extended(xKey))
171-
}
172-
}
184+
try encodeExtensions(to: &container)
173185
}
174186
}
175187

@@ -256,3 +268,54 @@ extension OpenAPI.Content {
256268
}
257269
}
258270
}
271+
272+
// MARK: Content.Encoding
273+
274+
extension OpenAPI.Content.Encoding: Encodable {
275+
public func encode(to encoder: Encoder) throws {
276+
var container = encoder.container(keyedBy: CodingKeys.self)
277+
278+
try contentType.encodeIfNotNil(to: &container, forKey: .contentType)
279+
280+
try headers.encodeIfNotNil(to: &container, forKey: .headers)
281+
282+
if style != Self.defaultStyle {
283+
try container.encode(style, forKey: .style)
284+
}
285+
286+
if explode != style.defaultExplode {
287+
try container.encode(explode, forKey: .explode)
288+
}
289+
290+
if allowReserved != false {
291+
try container.encode(allowReserved, forKey: .allowReserved)
292+
}
293+
}
294+
}
295+
296+
extension OpenAPI.Content.Encoding: Decodable {
297+
public init(from decoder: Decoder) throws {
298+
let container = try decoder.container(keyedBy: CodingKeys.self)
299+
300+
contentType = try container.decodeIfPresent(OpenAPI.ContentType.self, forKey: .contentType)
301+
302+
headers = try container.decodeIfPresent(OpenAPI.Header.Map.self, forKey: .headers)
303+
304+
let style: Style = try container.decodeIfPresent(Style.self, forKey: .style) ?? Self.defaultStyle
305+
self.style = style
306+
307+
explode = try container.decodeIfPresent(Bool.self, forKey: .explode) ?? style.defaultExplode
308+
309+
allowReserved = try container.decodeIfPresent(Bool.self, forKey: .allowReserved) ?? false
310+
}
311+
}
312+
313+
extension OpenAPI.Content.Encoding {
314+
private enum CodingKeys: String, CodingKey {
315+
case contentType
316+
case headers
317+
case style
318+
case explode
319+
case allowReserved
320+
}
321+
}

Sources/OpenAPIKit/Discriminator.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// File.swift
2+
// Discriminator.swift
33
//
44
//
55
// Created by Mathew Polzin on 10/6/19.
@@ -8,7 +8,7 @@
88
import Foundation
99

1010
extension OpenAPI {
11-
public struct Discriminator: Equatable, Codable {
11+
public struct Discriminator: Equatable {
1212
public let propertyName: String
1313
public let mapping: [String: String]?
1414

@@ -19,3 +19,32 @@ extension OpenAPI {
1919
}
2020
}
2121
}
22+
23+
// MARK: - Codable
24+
25+
extension OpenAPI.Discriminator: Encodable {
26+
public func encode(to encoder: Encoder) throws {
27+
var container = encoder.container(keyedBy: CodingKeys.self)
28+
29+
try container.encode(propertyName, forKey: .propertyName)
30+
31+
try mapping.encodeIfNotNil(to: &container, forKey: .mapping)
32+
}
33+
}
34+
35+
extension OpenAPI.Discriminator: Decodable {
36+
public init(from decoder: Decoder) throws {
37+
let container = try decoder.container(keyedBy: CodingKeys.self)
38+
39+
propertyName = try container.decode(String.self, forKey: .propertyName)
40+
41+
mapping = try container.decodeIfPresent([String: String].self, forKey: .mapping)
42+
}
43+
}
44+
45+
extension OpenAPI.Discriminator {
46+
private enum CodingKeys: String, CodingKey {
47+
case propertyName
48+
case mapping
49+
}
50+
}

Sources/OpenAPIKit/Document.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,7 @@ extension OpenAPI.Document: Encodable {
159159
try container.encode(encodableTags, forKey: .tags)
160160
}
161161

162-
if externalDocs != nil {
163-
try container.encode(externalDocs, forKey: .externalDocs)
164-
}
162+
try externalDocs.encodeIfNotNil(to: &container, forKey: .externalDocs)
165163
}
166164
}
167165

Sources/OpenAPIKit/Example.swift

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,9 @@ extension OpenAPI.Example: Encodable {
4545
public func encode(to encoder: Encoder) throws {
4646
var container = encoder.container(keyedBy: CodingKeys.self)
4747

48-
if summary != nil {
49-
try container.encode(summary, forKey: .summary)
50-
}
48+
try summary.encodeIfNotNil(to: &container, forKey: .summary)
5149

52-
if description != nil {
53-
try container.encode(description, forKey: .description)
54-
}
50+
try description.encodeIfNotNil(to: &container, forKey: .description)
5551

5652
switch value {
5753
case .a(let url):
@@ -60,9 +56,7 @@ extension OpenAPI.Example: Encodable {
6056
try container.encode(example, forKey: .value)
6157
}
6258

63-
for (key, value) in vendorExtensions {
64-
try container.encode(value, forKey: .extended(key))
65-
}
59+
try encodeExtensions(to: &container)
6660
}
6761
}
6862

Sources/OpenAPIKit/ExternalDoc.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import Foundation
99

1010
extension OpenAPI {
11-
public struct ExternalDoc: Codable, Equatable {
11+
public struct ExternalDoc: Equatable {
1212
public let description: String?
1313
public let url: URL
1414

@@ -19,3 +19,32 @@ extension OpenAPI {
1919
}
2020
}
2121
}
22+
23+
// MARK: - Codable
24+
25+
extension OpenAPI.ExternalDoc: Encodable {
26+
public func encode(to encoder: Encoder) throws {
27+
var container = encoder.container(keyedBy: CodingKeys.self)
28+
29+
try description.encodeIfNotNil(to: &container, forKey: .description)
30+
31+
try container.encode(url, forKey: .url)
32+
}
33+
}
34+
35+
extension OpenAPI.ExternalDoc: Decodable {
36+
public init(from decoder: Decoder) throws {
37+
let container = try decoder.container(keyedBy: CodingKeys.self)
38+
39+
description = try container.decodeIfPresent(String.self, forKey: .description)
40+
41+
url = try container.decode(URL.self, forKey: .url)
42+
}
43+
}
44+
45+
extension OpenAPI.ExternalDoc {
46+
private enum CodingKeys: String, CodingKey {
47+
case description
48+
case url
49+
}
50+
}

Sources/OpenAPIKit/Header.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ extension OpenAPI.Header: Encodable {
6666
try container.encode(stringKeyedDict, forKey: .content)
6767
}
6868

69-
if description != nil {
70-
try container.encode(description, forKey: .description)
71-
}
69+
try description.encodeIfNotNil(to: &container, forKey: .description)
7270

7371
if deprecated {
7472
try container.encode(deprecated, forKey: .deprecated)

Sources/OpenAPIKit/JSON Utility/JSONReference.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Reference.swift
2+
// JSONReference.swift
33
//
44
//
55
// Created by Mathew Polzin on 6/22/19.

Sources/OpenAPIKit/Path Item/Operation.swift

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,19 @@ extension OpenAPI.PathItem.Operation: Encodable {
7070
public func encode(to encoder: Encoder) throws {
7171
var container = encoder.container(keyedBy: CodingKeys.self)
7272

73-
if tags != nil {
74-
try container.encode(tags, forKey: .tags)
75-
}
73+
try tags.encodeIfNotNil(to: &container, forKey: .tags)
7674

77-
if summary != nil {
78-
try container.encode(summary, forKey: .summary)
79-
}
75+
try summary.encodeIfNotNil(to: &container, forKey: .summary)
8076

81-
if description != nil {
82-
try container.encode(description, forKey: .description)
83-
}
77+
try description.encodeIfNotNil(to: &container, forKey: .description)
8478

85-
if externalDocs != nil {
86-
try container.encode(externalDocs, forKey: .externalDocs)
87-
}
79+
try externalDocs.encodeIfNotNil(to: &container, forKey: .externalDocs)
8880

89-
if operationId != nil {
90-
try container.encode(operationId, forKey: .operationId)
91-
}
81+
try operationId.encodeIfNotNil(to: &container, forKey: .operationId)
9282

9383
try container.encode(parameters, forKey: .parameters)
9484

95-
if requestBody != nil {
96-
try container.encode(requestBody, forKey: .requestBody)
97-
}
85+
try requestBody.encodeIfNotNil(to: &container, forKey: .requestBody)
9886

9987
// Hack to work around Dictionary encoding
10088
// itself as an array in this case:
@@ -106,9 +94,7 @@ extension OpenAPI.PathItem.Operation: Encodable {
10694

10795
try container.encode(deprecated, forKey: .deprecated)
10896

109-
if servers != nil {
110-
try container.encode(servers, forKey: .servers)
111-
}
97+
try servers.encodeIfNotNil(to: &container, forKey: .servers)
11298
}
11399
}
114100

Sources/OpenAPIKit/Path Item/Parameter.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,7 @@ extension OpenAPI.PathItem.Parameter: Encodable {
374374
try container.encode(stringKeyedDict, forKey: .content)
375375
}
376376

377-
if description != nil {
378-
try container.encode(description, forKey: .description)
379-
}
377+
try description.encodeIfNotNil(to: &container, forKey: .description)
380378

381379
if deprecated {
382380
try container.encode(deprecated, forKey: .deprecated)

Sources/OpenAPIKit/Path Item/PathItem.swift

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -170,51 +170,22 @@ extension OpenAPI.PathItem: Encodable {
170170
public func encode(to encoder: Encoder) throws {
171171
var container = encoder.container(keyedBy: CodingKeys.self)
172172

173-
if summary != nil {
174-
try container.encode(summary, forKey: .summary)
175-
}
173+
try summary.encodeIfNotNil(to: &container, forKey: .summary)
176174

177-
if description != nil {
178-
try container.encode(description, forKey: .description)
179-
}
175+
try description.encodeIfNotNil(to: &container, forKey: .description)
180176

181-
if servers != nil {
182-
try container.encode(servers, forKey: .servers)
183-
}
177+
try servers.encodeIfNotNil(to: &container, forKey: .servers)
184178

185179
try container.encode(parameters, forKey: .parameters)
186180

187-
if get != nil {
188-
try container.encode(get, forKey: .get)
189-
}
190-
191-
if put != nil {
192-
try container.encode(put, forKey: .put)
193-
}
194-
195-
if post != nil {
196-
try container.encode(post, forKey: .post)
197-
}
198-
199-
if delete != nil {
200-
try container.encode(delete, forKey: .delete)
201-
}
202-
203-
if options != nil {
204-
try container.encode(options, forKey: .options)
205-
}
206-
207-
if head != nil {
208-
try container.encode(head, forKey: .head)
209-
}
210-
211-
if patch != nil {
212-
try container.encode(patch, forKey: .patch)
213-
}
214-
215-
if trace != nil {
216-
try container.encode(trace, forKey: .trace)
217-
}
181+
try get.encodeIfNotNil(to: &container, forKey: .get)
182+
try put.encodeIfNotNil(to: &container, forKey: .put)
183+
try post.encodeIfNotNil(to: &container, forKey: .post)
184+
try delete.encodeIfNotNil(to: &container, forKey: .delete)
185+
try options.encodeIfNotNil(to: &container, forKey: .options)
186+
try head.encodeIfNotNil(to: &container, forKey: .head)
187+
try patch.encodeIfNotNil(to: &container, forKey: .patch)
188+
try trace.encodeIfNotNil(to: &container, forKey: .trace)
218189
}
219190
}
220191

0 commit comments

Comments
 (0)