@@ -4567,6 +4567,140 @@ final class SnippetBasedReferenceTests: XCTestCase {
45674567 )
45684568 }
45694569
4570+ func testRequestMultipartBodyAdditionalPropertiesSchemaBuiltin( ) throws {
4571+ try self . assertRequestInTypesClientServerTranslation (
4572+ """
4573+ /foo:
4574+ post:
4575+ requestBody:
4576+ required: true
4577+ content:
4578+ multipart/form-data:
4579+ schema:
4580+ type: object
4581+ additionalProperties:
4582+ type: string
4583+ responses:
4584+ default:
4585+ description: Response
4586+ """ ,
4587+ types: """
4588+ public struct Input: Sendable, Hashable {
4589+ @frozen public enum Body: Sendable, Hashable {
4590+ @frozen public enum multipartFormPayload: Sendable, Hashable {
4591+ case additionalProperties(OpenAPIRuntime.MultipartDynamicallyNamedPart<OpenAPIRuntime.HTTPBody>)
4592+ }
4593+ case multipartForm(OpenAPIRuntime.MultipartBody<Operations.post_sol_foo.Input.Body.multipartFormPayload>)
4594+ }
4595+ public var body: Operations.post_sol_foo.Input.Body
4596+ public init(body: Operations.post_sol_foo.Input.Body) {
4597+ self.body = body
4598+ }
4599+ }
4600+ """ ,
4601+ client: """
4602+ { input in
4603+ let path = try converter.renderedPath(
4604+ template: " /foo " ,
4605+ parameters: []
4606+ )
4607+ var request: HTTPTypes.HTTPRequest = .init(
4608+ soar_path: path,
4609+ method: .post
4610+ )
4611+ suppressMutabilityWarning(&request)
4612+ let body: OpenAPIRuntime.HTTPBody?
4613+ switch input.body {
4614+ case let .multipartForm(value):
4615+ body = try converter.setRequiredRequestBodyAsMultipart(
4616+ value,
4617+ headerFields: &request.headerFields,
4618+ contentType: " multipart/form-data " ,
4619+ allowsUnknownParts: true,
4620+ requiredExactlyOncePartNames: [],
4621+ requiredAtLeastOncePartNames: [],
4622+ atMostOncePartNames: [],
4623+ zeroOrMoreTimesPartNames: [],
4624+ encoding: { part in
4625+ switch part {
4626+ case let .additionalProperties(wrapped):
4627+ var headerFields: HTTPTypes.HTTPFields = .init()
4628+ let value = wrapped.payload
4629+ let body = try converter.setRequiredRequestBodyAsBinary(
4630+ value,
4631+ headerFields: &headerFields,
4632+ contentType: " text/plain "
4633+ )
4634+ return .init(
4635+ name: wrapped.name,
4636+ filename: wrapped.filename,
4637+ headerFields: headerFields,
4638+ body: body
4639+ )
4640+ }
4641+ }
4642+ )
4643+ }
4644+ return (request, body)
4645+ }
4646+ """ ,
4647+ server: """
4648+ { request, requestBody, metadata in
4649+ let contentType = converter.extractContentTypeIfPresent(in: request.headerFields)
4650+ let body: Operations.post_sol_foo.Input.Body
4651+ let chosenContentType = try converter.bestContentType(
4652+ received: contentType,
4653+ options: [
4654+ " multipart/form-data "
4655+ ]
4656+ )
4657+ switch chosenContentType {
4658+ case " multipart/form-data " :
4659+ body = try converter.getRequiredRequestBodyAsMultipart(
4660+ OpenAPIRuntime.MultipartBody<Operations.post_sol_foo.Input.Body.multipartFormPayload>.self,
4661+ from: requestBody,
4662+ transforming: { value in
4663+ .multipartForm(value)
4664+ },
4665+ boundary: contentType.requiredBoundary(),
4666+ allowsUnknownParts: true,
4667+ requiredExactlyOncePartNames: [],
4668+ requiredAtLeastOncePartNames: [],
4669+ atMostOncePartNames: [],
4670+ zeroOrMoreTimesPartNames: [],
4671+ decoding: { part in
4672+ let headerFields = part.headerFields
4673+ let (name, filename) = try converter.extractContentDispositionNameAndFilename(in: headerFields)
4674+ switch name {
4675+ default:
4676+ try converter.verifyContentTypeIfPresent(
4677+ in: headerFields,
4678+ matches: " text/plain "
4679+ )
4680+ let body = try converter.getRequiredRequestBodyAsBinary(
4681+ OpenAPIRuntime.HTTPBody.self,
4682+ from: part.body,
4683+ transforming: {
4684+ $0
4685+ }
4686+ )
4687+ return .additionalProperties(.init(
4688+ payload: body,
4689+ filename: filename,
4690+ name: name
4691+ ))
4692+ }
4693+ }
4694+ )
4695+ default:
4696+ preconditionFailure( " bestContentType chose an invalid content type. " )
4697+ }
4698+ return Operations.post_sol_foo.Input(body: body)
4699+ }
4700+ """
4701+ )
4702+ }
4703+
45704704 func testResponseMultipartReferencedResponse( ) throws {
45714705 try self . assertResponseInTypesClientServerTranslation (
45724706 """
@@ -5323,7 +5457,7 @@ private func XCTAssertSwiftEquivalent(
53235457}
53245458
53255459private func XCTAssertSwiftEquivalent(
5326- _ expression: Expression ,
5460+ _ expression: _OpenAPIGeneratorCore . Expression ,
53275461 _ expectedSwift: String ,
53285462 file: StaticString = #filePath,
53295463 line: UInt = #line
0 commit comments