Skip to content

Commit 538c735

Browse files
committed
Support nested values in OpenAPIObjectContainer
1 parent fbd56ae commit 538c735

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

Sources/OpenAPIRuntime/Base/OpenAPIValue.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,18 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {
143143
try container.encode(value.map(OpenAPIValueContainer.init(validatedValue:)))
144144
case let value as [String: OpenAPIValueContainer?]:
145145
try container.encode(value.mapValues(OpenAPIValueContainer.init(validatedValue:)))
146+
case let value as [Sendable?]:
147+
try container.encode(
148+
value.map {
149+
try OpenAPIValueContainer.init(unvalidatedValue: $0)
150+
}
151+
)
152+
case let value as [String: Sendable?]:
153+
try container.encode(
154+
value.mapValues {
155+
try OpenAPIValueContainer.init(unvalidatedValue: $0)
156+
}
157+
)
146158
default:
147159
throw EncodingError.invalidValue(
148160
value,

Tests/OpenAPIRuntimeTests/Conversion/Test_CodableExtensions.swift

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,92 @@ final class Test_CodableExtensions: Test_Runtime {
288288
)
289289
}
290290
}
291+
292+
func testEncodeNested_true() throws {
293+
294+
struct Foo: Encodable {
295+
var bar: String
296+
var dict: OpenAPIObjectContainer = .init()
297+
}
298+
299+
do {
300+
let value = Foo(
301+
bar: "hi",
302+
dict: try .init(unvalidatedValue: [
303+
"baz": "bar",
304+
"number": 1,
305+
"nestedArray": [
306+
1,
307+
[
308+
"k": "v"
309+
],
310+
],
311+
"nestedDict": [
312+
"nested": 2
313+
],
314+
])
315+
)
316+
let data = try testEncoder.encode(value)
317+
XCTAssertEqual(
318+
String(decoding: data, as: UTF8.self),
319+
#"""
320+
{
321+
"bar" : "hi",
322+
"dict" : {
323+
"baz" : "bar",
324+
"nestedArray" : [
325+
1,
326+
{
327+
"k" : "v"
328+
}
329+
],
330+
"nestedDict" : {
331+
"nested" : 2
332+
},
333+
"number" : 1
334+
}
335+
}
336+
"""#
337+
)
338+
}
339+
}
340+
341+
func testDecodeEncodeRoundTripNested_true() throws {
342+
343+
struct Foo: Codable {
344+
var bar: String
345+
var dict: OpenAPIObjectContainer = .init()
346+
}
347+
348+
do {
349+
let data = Data(
350+
#"""
351+
{
352+
"bar" : "hi",
353+
"dict" : {
354+
"baz" : "bar",
355+
"nestedArray" : [
356+
1,
357+
{
358+
"k" : "v"
359+
}
360+
],
361+
"nestedDict" : {
362+
"nested" : 2
363+
},
364+
"number" : 1
365+
}
366+
}
367+
"""#
368+
.utf8
369+
)
370+
let decoded = try testDecoder.decode(Foo.self, from: data)
371+
let nestedDict = try XCTUnwrap(decoded.dict.value["nestedDict"] as? [String: Any?])
372+
let nestedValue = try XCTUnwrap(nestedDict["nested"] as? Int)
373+
XCTAssertEqual(nestedValue, 2)
374+
375+
let encodedData = try testEncoder.encode(decoded)
376+
XCTAssertEqual(encodedData, data)
377+
}
378+
}
291379
}

0 commit comments

Comments
 (0)