Skip to content

Commit 10d75e0

Browse files
committed
merge w/ main
2 parents 15147d8 + a75aa41 commit 10d75e0

File tree

4 files changed

+157
-28
lines changed

4 files changed

+157
-28
lines changed

Sources/OpenAPIKit/Schema Object/JSONSchema.swift

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,10 @@ extension JSONSchema: Decodable {
19761976
schema = schema.nullableSchemaObject()
19771977
}
19781978

1979-
self = schema
1979+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1980+
let extensions = try Self.decodeVenderExtensions(from: decoder)
1981+
1982+
self = schema.with(vendorExtensions: extensions)
19801983
return
19811984
}
19821985

@@ -1993,7 +1996,10 @@ extension JSONSchema: Decodable {
19931996
schema = schema.nullableSchemaObject()
19941997
}
19951998

1996-
self = schema
1999+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
2000+
let extensions = try Self.decodeVenderExtensions(from: decoder)
2001+
2002+
self = schema.with(vendorExtensions: extensions)
19972003
return
19982004
}
19992005

@@ -2009,7 +2015,10 @@ extension JSONSchema: Decodable {
20092015
schema = schema.nullableSchemaObject()
20102016
}
20112017

2012-
self = schema
2018+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
2019+
let extensions = try Self.decodeVenderExtensions(from: decoder)
2020+
2021+
self = schema.with(vendorExtensions: extensions)
20132022
return
20142023
}
20152024

@@ -2021,8 +2030,11 @@ extension JSONSchema: Decodable {
20212030
core: coreContext
20222031
)
20232032
)
2024-
2025-
self = schema
2033+
2034+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
2035+
let extensions = try Self.decodeVenderExtensions(from: decoder)
2036+
2037+
self = schema.with(vendorExtensions: extensions)
20262038
return
20272039
}
20282040

@@ -2137,29 +2149,30 @@ extension JSONSchema: Decodable {
21372149

21382150
self.warnings = _warnings
21392151

2140-
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
2141-
let extensions: [String: AnyCodable]
2152+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
2153+
let extensions = try Self.decodeVenderExtensions(from: decoder)
21422154

2155+
self.value = value.with(vendorExtensions: extensions)
2156+
}
2157+
2158+
private static func decodeVenderExtensions(from decoder: Decoder) throws -> [String: AnyCodable] {
21432159
guard VendorExtensionsConfiguration.isEnabled(for: decoder) else {
2144-
self.value = value
2145-
return
2160+
return [:]
21462161
}
2147-
2162+
21482163
let decoded = try AnyCodable(from: decoder).value
2149-
2164+
21502165
guard (decoded as? [Any]) == nil else {
21512166
throw VendorExtensionDecodingError.selfIsArrayNotDict
21522167
}
21532168

21542169
guard let decodedAny = decoded as? [String: any Sendable] else {
21552170
throw VendorExtensionDecodingError.foundNonStringKeys
21562171
}
2157-
2158-
extensions = decodedAny
2172+
2173+
return decodedAny
21592174
.filter { $0.key.lowercased().starts(with: "x-") }
21602175
.mapValues(AnyCodable.init)
2161-
2162-
self.value = value.with(vendorExtensions: extensions)
21632176
}
21642177

21652178
private static func decodeTypes(from container: KeyedDecodingContainer<JSONSchema.HintCodingKeys>) throws -> [JSONType] {

Sources/OpenAPIKit30/Schema Object/JSONSchema.swift

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,9 @@ extension JSONSchema: Decodable {
17621762
schema = schema.nullableSchemaObject()
17631763
}
17641764

1765-
self = schema
1765+
self = .init(warnings: schema.warnings,
1766+
schema: schema.value,
1767+
vendorExtensions: try Self.decodeVenderExtensions(from: decoder))
17661768
return
17671769
}
17681770

@@ -1775,7 +1777,9 @@ extension JSONSchema: Decodable {
17751777
schema = schema.nullableSchemaObject()
17761778
}
17771779

1778-
self = schema
1780+
self = .init(warnings: schema.warnings,
1781+
schema: schema.value,
1782+
vendorExtensions: try Self.decodeVenderExtensions(from: decoder))
17791783
return
17801784
}
17811785

@@ -1788,7 +1792,9 @@ extension JSONSchema: Decodable {
17881792
schema = schema.nullableSchemaObject()
17891793
}
17901794

1791-
self = schema
1795+
self = .init(warnings: schema.warnings,
1796+
schema: schema.value,
1797+
vendorExtensions: try Self.decodeVenderExtensions(from: decoder))
17921798
return
17931799
}
17941800

@@ -1798,7 +1804,9 @@ extension JSONSchema: Decodable {
17981804
core: try CoreContext<JSONTypeFormat.AnyFormat>(from: decoder)
17991805
)
18001806

1801-
self = schema
1807+
self = .init(warnings: schema.warnings,
1808+
schema: schema.value,
1809+
vendorExtensions: try Self.decodeVenderExtensions(from: decoder))
18021810
return
18031811
}
18041812

@@ -1889,25 +1897,27 @@ extension JSONSchema: Decodable {
18891897

18901898
self.warnings = _warnings
18911899

1892-
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1900+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
1901+
}
1902+
1903+
private static func decodeVenderExtensions(from decoder: Decoder) throws -> [String: AnyCodable] {
18931904
guard VendorExtensionsConfiguration.isEnabled(for: decoder) else {
1894-
self.vendorExtensions = [:]
1895-
return
1905+
return [:]
18961906
}
1897-
1907+
18981908
let decoded = try AnyCodable(from: decoder).value
1899-
1909+
19001910
guard (decoded as? [Any]) == nil else {
19011911
throw VendorExtensionDecodingError.selfIsArrayNotDict
19021912
}
19031913

19041914
guard let decodedAny = decoded as? [String: any Sendable] else {
19051915
throw VendorExtensionDecodingError.foundNonStringKeys
19061916
}
1907-
1908-
let extensions = decodedAny.filter { $0.key.lowercased().starts(with: "x-") }
1909-
1910-
self.vendorExtensions = extensions.mapValues(AnyCodable.init)
1917+
1918+
return decodedAny
1919+
.filter { $0.key.lowercased().starts(with: "x-") }
1920+
.mapValues(AnyCodable.init)
19111921
}
19121922
}
19131923

Tests/OpenAPIKit30Tests/Schema Object/JSONSchemaTests.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,61 @@ extension SchemaObjectTests {
15301530
)
15311531
}
15321532

1533+
func test_decodeAnyOfWithVendorExtension() throws {
1534+
let extensionSchema = """
1535+
{
1536+
"anyOf" : [
1537+
{ "type": "string" },
1538+
{ "type": "number" }
1539+
],
1540+
"x-hello" : "hello"
1541+
}
1542+
""".data(using: .utf8)!
1543+
1544+
let desiredSchema = JSONSchema(schema: .any(of: [JSONSchema.string, JSONSchema.number], core: .init()), vendorExtensions: ["x-hello": "hello"])
1545+
XCTAssertEqual(
1546+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1547+
desiredSchema
1548+
)
1549+
}
1550+
1551+
func test_decodeAllOfWithVendorExtension() throws {
1552+
let extensionSchema = """
1553+
{
1554+
"allOf" : [
1555+
{ "type": "string" },
1556+
{ "type": "number" }
1557+
],
1558+
"x-hello" : "hello"
1559+
}
1560+
""".data(using: .utf8)!
1561+
1562+
let desiredSchema = JSONSchema(schema: .all(of: [JSONSchema.string, JSONSchema.number], core: .init()), vendorExtensions: ["x-hello": "hello"])
1563+
XCTAssertEqual(
1564+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1565+
desiredSchema
1566+
)
1567+
}
1568+
1569+
func test_decodeOneOfWithVendorExtension() throws {
1570+
let extensionSchema = """
1571+
{
1572+
"oneOf" : [
1573+
{ "type": "string" },
1574+
{ "type": "number" }
1575+
],
1576+
"x-hello" : "hello"
1577+
}
1578+
""".data(using: .utf8)!
1579+
1580+
let desiredSchema = JSONSchema(schema: .one(of: [JSONSchema.string, JSONSchema.number], core: .init()), vendorExtensions: ["x-hello": "hello"])
1581+
XCTAssertEqual(
1582+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1583+
desiredSchema
1584+
)
1585+
}
1586+
1587+
15331588
func test_encodeBoolean() {
15341589
let requiredBoolean = JSONSchema.boolean(.init(format: .unspecified, required: true))
15351590
let optionalBoolean = JSONSchema.boolean(.init(format: .unspecified, required: false))

Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,6 +1934,57 @@ extension SchemaObjectTests {
19341934
"""
19351935
)
19361936
}
1937+
1938+
func test_decodeAnyOfWithVendorExtension() throws {
1939+
let extensionSchema = """
1940+
{
1941+
"anyOf" : [
1942+
{ "type": "string" },
1943+
{ "type": "number" }
1944+
],
1945+
"x-hello" : "hello"
1946+
}
1947+
""".data(using: .utf8)!
1948+
1949+
XCTAssertEqual(
1950+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1951+
JSONSchema.any(of: [JSONSchema.string, JSONSchema.number]).with(vendorExtensions: ["x-hello": "hello"])
1952+
)
1953+
}
1954+
1955+
func test_decodeAllOfWithVendorExtension() throws {
1956+
let extensionSchema = """
1957+
{
1958+
"allOf" : [
1959+
{ "type": "string" },
1960+
{ "type": "number" }
1961+
],
1962+
"x-hello" : "hello"
1963+
}
1964+
""".data(using: .utf8)!
1965+
1966+
XCTAssertEqual(
1967+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1968+
JSONSchema.all(of: [JSONSchema.string, JSONSchema.number]).with(vendorExtensions: ["x-hello": "hello"])
1969+
)
1970+
}
1971+
1972+
func test_decodeOneOfWithVendorExtension() throws {
1973+
let extensionSchema = """
1974+
{
1975+
"oneOf" : [
1976+
{ "type": "string" },
1977+
{ "type": "number" }
1978+
],
1979+
"x-hello" : "hello"
1980+
}
1981+
""".data(using: .utf8)!
1982+
1983+
XCTAssertEqual(
1984+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1985+
JSONSchema.one(of: [JSONSchema.string, JSONSchema.number]).with(vendorExtensions: ["x-hello": "hello"])
1986+
)
1987+
}
19371988

19381989
func test_decodeNullType() throws {
19391990
let nullTypeData = """

0 commit comments

Comments
 (0)