Skip to content

Commit a14f44b

Browse files
committed
Add XML coding strategy
1 parent 7b4dd6b commit a14f44b

File tree

8 files changed

+36
-10
lines changed

8 files changed

+36
-10
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift

+3
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ enum Constants {
371371

372372
/// The substring used in method names for the multipart coding strategy.
373373
static let multipart: String = "Multipart"
374+
375+
/// The substring used in method names for the XML coding strategy.
376+
static let xml: String = "XML"
374377
}
375378

376379
/// Constants related to types used in many components.

Sources/_OpenAPIGeneratorCore/Translator/Content/CodingStrategy.swift

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ enum CodingStrategy: String, Hashable, Sendable {
3030
/// A strategy using multipart/form-data.
3131
case multipart
3232

33+
/// A strategy using optional CustomCoder.
34+
case xml
35+
3336
/// The name of the coding strategy in the runtime library.
3437
var runtimeName: String {
3538
switch self {
@@ -38,6 +41,7 @@ enum CodingStrategy: String, Hashable, Sendable {
3841
case .binary: return Constants.CodingStrategy.binary
3942
case .urlEncodedForm: return Constants.CodingStrategy.urlEncodedForm
4043
case .multipart: return Constants.CodingStrategy.multipart
44+
case .xml: return Constants.CodingStrategy.xml
4145
}
4246
}
4347
}

Sources/_OpenAPIGeneratorCore/Translator/Content/ContentInspector.swift

+9-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ extension FileTranslator {
2020
///
2121
/// Priority:
2222
/// 1. JSON
23-
/// 2. text
24-
/// 3. binary
23+
/// 2. XML
24+
/// 3. text
25+
/// 4. binary
2526
///
2627
/// - Parameters:
2728
/// - map: The content map from the OpenAPI document.
@@ -108,8 +109,9 @@ extension FileTranslator {
108109
///
109110
/// Priority:
110111
/// 1. JSON
111-
/// 2. text
112-
/// 3. binary
112+
/// 2. XML
113+
/// 3. text
114+
/// 4. binary
113115
///
114116
/// - Parameters:
115117
/// - map: The content map from the OpenAPI document.
@@ -127,7 +129,7 @@ extension FileTranslator {
127129
let mapWithContentTypes = try map.map { key, content in try (type: key.asGeneratorContentType, value: content) }
128130

129131
let chosenContent: (type: ContentType, schema: SchemaContent, content: OpenAPI.Content)?
130-
if let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isJSON }) {
132+
if let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isJSON || $0.type.isXml }) {
131133
chosenContent = (contentType, .init(contentType: contentType, schema: contentValue.schema), contentValue)
132134
} else if !excludeBinary,
133135
let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isBinary })
@@ -160,6 +162,7 @@ extension FileTranslator {
160162
///
161163
/// Priority of checking for known MIME types:
162164
/// 1. JSON
165+
/// 2. XML
163166
/// 2. text
164167
/// 3. binary
165168
///
@@ -188,6 +191,7 @@ extension FileTranslator {
188191
)
189192
}
190193
if contentType.isJSON { return .init(contentType: contentType, schema: contentValue.schema) }
194+
if contentType.isXml { return .init(contentType: contentType, schema: contentValue.schema) }
191195
if contentType.isUrlEncodedForm { return .init(contentType: contentType, schema: contentValue.schema) }
192196
if contentType.isMultipart {
193197
guard isRequired else {

Sources/_OpenAPIGeneratorCore/Translator/Content/ContentType.swift

+16-1
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,14 @@ struct ContentType: Hashable {
5656
/// The type is encoded as an async sequence of parts.
5757
case multipart
5858

59+
/// A content type for XML.
60+
///
61+
/// The bytes are provided to a CustomCoder.
62+
case xml
63+
5964
/// Creates a category from the provided type and subtype.
6065
///
61-
/// First checks if the provided content type is a JSON, then text,
66+
/// First checks if the provided content type is a JSON, then XML, then text,
6267
/// and uses binary if none of the two match.
6368
/// - Parameters:
6469
/// - lowercasedType: The first component of the MIME type.
@@ -68,6 +73,10 @@ struct ContentType: Hashable {
6873
if (lowercasedType == "application" && lowercasedSubtype == "json") || lowercasedSubtype.hasSuffix("+json")
6974
{
7075
self = .json
76+
} else if (lowercasedType == "application" && lowercasedSubtype == "xml")
77+
|| lowercasedSubtype.hasSuffix("+xml")
78+
{
79+
self = .xml
7180
} else if lowercasedType == "application" && lowercasedSubtype == "x-www-form-urlencoded" {
7281
self = .urlEncodedForm
7382
} else if lowercasedType == "multipart" && lowercasedSubtype == "form-data" {
@@ -84,6 +93,7 @@ struct ContentType: Hashable {
8493
case .binary: return .binary
8594
case .urlEncodedForm: return .urlEncodedForm
8695
case .multipart: return .multipart
96+
case .xml: return .xml
8797
}
8898
}
8999
}
@@ -214,12 +224,17 @@ struct ContentType: Hashable {
214224
/// A Boolean value that indicates whether the content type
215225
/// is a multipart form.
216226
var isMultipart: Bool { category == .multipart }
227+
/// A Boolean value that indicates whether the content type
228+
/// is a type of XML.
229+
var isXml: Bool { category == .xml }
217230

218231
/// The content type `text/plain`.
219232
static var textPlain: Self { try! .init(string: "text/plain") }
220233

221234
/// The content type `application/json`.
222235
static var applicationJSON: Self { try! .init(string: "application/json") }
236+
/// The content type `application/xml`.
237+
static var applicationXML: Self { try! .init(string: "application/xml") }
223238

224239
/// The content type `application/octet-stream`.
225240
static var applicationOctetStream: Self { try! .init(string: "application/octet-stream") }

Sources/_OpenAPIGeneratorCore/Translator/Multipart/translateMultipart.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ extension FileTranslator {
353353
])
354354
let bodyExpr: Expression
355355
switch codingStrategy {
356-
case .json, .uri, .urlEncodedForm:
356+
case .json, .xml, .uri, .urlEncodedForm:
357357
// Buffering.
358358
bodyExpr = .try(.await(converterExpr))
359359
case .binary, .multipart:

Sources/_OpenAPIGeneratorCore/Translator/RequestBody/translateRequestBody.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ extension ServerFileTranslator {
275275
)
276276
let bodyExpr: Expression
277277
switch codingStrategy {
278-
case .json, .uri, .urlEncodedForm:
278+
case .json, .xml, .uri, .urlEncodedForm:
279279
// Buffering.
280280
bodyExpr = .try(.await(converterExpr))
281281
case .binary, .multipart:

Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponseOutcome.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ extension ClientFileTranslator {
267267
)
268268
let bodyExpr: Expression
269269
switch codingStrategy {
270-
case .json, .uri, .urlEncodedForm:
270+
case .json, .xml, .uri, .urlEncodedForm:
271271
// Buffering.
272272
bodyExpr = .try(.await(converterExpr))
273273
case .binary, .multipart:

Tests/OpenAPIGeneratorCoreTests/Translator/Content/Test_ContentType.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ final class Test_ContentType: Test_Core {
4646
), ("text/plain", .binary, "text", "plain", "", "text/plain", "text/plain", "text/plain"),
4747
("*/*", .binary, "*", "*", "", "*/*", "*/*", "*/*"),
4848
(
49-
"application/xml", .binary, "application", "xml", "", "application/xml", "application/xml",
49+
"application/xml", .xml, "application", "xml", "", "application/xml", "application/xml",
5050
"application/xml"
5151
),
5252
(

0 commit comments

Comments
 (0)