Skip to content

Commit 1948f07

Browse files
committed
Add XML coding strategy
1 parent 84b693f commit 1948f07

File tree

8 files changed

+36
-10
lines changed

8 files changed

+36
-10
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift

Lines changed: 3 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ extension FileTranslator {
2121
///
2222
/// Priority:
2323
/// 1. JSON
24-
/// 2. text
25-
/// 3. binary
24+
/// 2. XML
25+
/// 3. text
26+
/// 4. binary
2627
///
2728
/// - Parameters:
2829
/// - map: The content map from the OpenAPI document.
@@ -109,8 +110,9 @@ extension FileTranslator {
109110
///
110111
/// Priority:
111112
/// 1. JSON
112-
/// 2. text
113-
/// 3. binary
113+
/// 2. XML
114+
/// 3. text
115+
/// 4. binary
114116
///
115117
/// - Parameters:
116118
/// - map: The content map from the OpenAPI document.
@@ -128,7 +130,7 @@ extension FileTranslator {
128130
let mapWithContentTypes = try map.map { key, content in try (type: key.asGeneratorContentType, value: content) }
129131

130132
let chosenContent: (type: ContentType, schema: SchemaContent, content: OpenAPI.Content)?
131-
if let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isJSON }) {
133+
if let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isJSON || $0.type.isXml }) {
132134
chosenContent = (contentType, .init(contentType: contentType, schema: contentValue.schema), contentValue)
133135
} else if !excludeBinary,
134136
let (contentType, contentValue) = mapWithContentTypes.first(where: { $0.type.isBinary })
@@ -161,6 +163,7 @@ extension FileTranslator {
161163
///
162164
/// Priority of checking for known MIME types:
163165
/// 1. JSON
166+
/// 2. XML
164167
/// 2. text
165168
/// 3. binary
166169
///
@@ -189,6 +192,7 @@ extension FileTranslator {
189192
)
190193
}
191194
if contentType.isJSON { return .init(contentType: contentType, schema: contentValue.schema) }
195+
if contentType.isXml { return .init(contentType: contentType, schema: contentValue.schema) }
192196
if contentType.isUrlEncodedForm { return .init(contentType: contentType, schema: contentValue.schema) }
193197
if contentType.isMultipart {
194198
guard isRequired else {

Sources/_OpenAPIGeneratorCore/Translator/Content/ContentType.swift

Lines changed: 16 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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)