From 628f8e756426bef8ed0c4e3ccd3f7d422e29ffeb Mon Sep 17 00:00:00 2001 From: Jorge Rangel Date: Mon, 13 Jan 2025 14:36:03 -0600 Subject: [PATCH] initial design --- .../Http/Payload/Multipart/MultipartTests.cs | 220 +++++++++++++ .../src/Generated/FormData.RestClient.cs | 129 ++++++++ .../multipart/src/Generated/FormData.cs | 306 +++++++++++++++++- .../Generated/FormDataHttpParts.RestClient.cs | 33 ++ .../src/Generated/FormDataHttpParts.cs | 72 ++++- ...FormDataHttpPartsContentType.RestClient.cs | 65 ++++ .../Generated/FormDataHttpPartsContentType.cs | 134 +++++++- .../FormDataHttpPartsNonString.RestClient.cs | 33 ++ .../Generated/FormDataHttpPartsNonString.cs | 58 +++- .../src/Generated/Internal/Argument.cs | 126 ++++++++ .../Internal/ClientPipelineExtensions.cs | 67 ++++ .../Generated/Internal/ClientUriBuilder.cs | 131 ++++++++ .../src/Generated/Internal/ErrorResult.cs | 23 ++ .../Internal/ModelSerializationExtensions.cs | 251 ++++++++++++++ .../MultiPartFormDataBinaryContent.cs | 270 ++++++++++++++-- .../src/Generated/Internal/Optional.cs | 47 +++ .../src/Generated/Internal/TypeFormatters.cs | 150 +++++++++ .../Generated/Models/Address.Serialization.cs | 141 ++++++++ .../multipart/src/Generated/Models/Address.cs | 27 ++ .../AnonymousModelRequest.Serialization.cs | 24 ++ .../Generated/Models/AnonymousModelRequest.cs | 28 ++ .../BinaryArrayPartsRequest.Serialization.cs | 21 ++ .../Models/BinaryArrayPartsRequest.cs | 29 ++ ...plexHttpPartsModelRequest.Serialization.cs | 28 ++ .../Models/ComplexHttpPartsModelRequest.cs | 29 ++ .../ComplexPartsRequest.Serialization.cs | 27 ++ .../Generated/Models/ComplexPartsRequest.cs | 32 ++ .../Models/FileOptionalContentType.cs | 22 ++ .../Generated/Models/FileRequiredMetaData.cs | 22 ++ .../Models/FileSpecificContentType.cs | 21 ++ .../FileSpecificContentTypeContentType.cs | 57 ++++ ...ptionalContentTypeRequest.Serialization.cs | 19 ++ ...eWithHttpPartOptionalContentTypeRequest.cs | 15 + ...equiredContentTypeRequest.Serialization.cs | 15 + ...eWithHttpPartRequiredContentTypeRequest.cs | 15 + ...pecificContentTypeRequest.Serialization.cs | 17 + ...eWithHttpPartSpecificContentTypeRequest.cs | 17 + .../Models/FloatRequest.Serialization.cs | 22 ++ .../src/Generated/Models/FloatRequest.cs | 16 + .../Models/FloatRequestTemperature.cs | 19 ++ .../FloatRequestTemperatureContentType.cs | 54 ++++ .../Models/JsonPartRequest.Serialization.cs | 21 ++ .../src/Generated/Models/JsonPartRequest.cs | 28 ++ .../MultiBinaryPartsRequest.Serialization.cs | 29 ++ .../Models/MultiBinaryPartsRequest.cs | 26 ++ .../Models/MultiPartRequest.Serialization.cs | 22 ++ .../src/Generated/Models/MultiPartRequest.cs | 24 ++ .../Generated/Models/PictureFileDetails.cs | 21 ++ .../Generated/Models/PicturesFileDetails.cs | 21 ++ .../Models/ProfileImageFileDetails.cs | 20 ++ .../Generated/MultiPartClient.RestClient.cs | 11 + .../src/Generated/MultiPartClient.cs | 33 +- .../src/Generated/MultiPartClientOptions.cs | 1 + 53 files changed, 3029 insertions(+), 60 deletions(-) create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Argument.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientPipelineExtensions.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientUriBuilder.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ErrorResult.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ModelSerializationExtensions.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Optional.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/TypeFormatters.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileOptionalContentType.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileRequiredMetaData.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentType.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentTypeContentType.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperature.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperatureContentType.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PictureFileDetails.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PicturesFileDetails.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ProfileImageFileDetails.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.RestClient.cs diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch.Tests/Http/Payload/Multipart/MultipartTests.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch.Tests/Http/Payload/Multipart/MultipartTests.cs index 1f3541ad25a..c54e5e8cd78 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch.Tests/Http/Payload/Multipart/MultipartTests.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch.Tests/Http/Payload/Multipart/MultipartTests.cs @@ -1,10 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using NUnit.Framework; using Payload.MultiPart; +using Payload.MultiPart.Models; using File = System.IO.File; namespace TestProjects.CadlRanch.Tests.Http.Payload.Multipart @@ -28,6 +30,23 @@ public Task Basic() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task BasicConv() => Test(async (host) => + { + var id = "123"; + await using var imageStream = File.OpenRead(SampleJpgPath); + + var profileImage = new ProfileImageFileDetails(imageStream) + { + Filename = "profileImage", + ContentType = "application/octet-stream" + }; + var request = new MultiPartRequest(id, profileImage); + var response = await new MultiPartClient(host, null).GetFormDataClient().BasicAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task JsonPart() => Test(async (host) => { @@ -42,6 +61,25 @@ public Task JsonPart() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task JsonPartConv() => Test(async (host) => + { + Address address = new Address("X"); + + await using var imageStream = File.OpenRead(SampleJpgPath); + var profileImage = new ProfileImageFileDetails(imageStream) + { + Filename = "profileImage", + ContentType = "application/octet-stream" + }; + + var request = new JsonPartRequest(address, profileImage); + + var response = await new MultiPartClient(host, null).GetFormDataClient().JsonPartAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task CheckFileNameAndContentType() => Test(async (host) => { @@ -56,6 +94,24 @@ public Task CheckFileNameAndContentType() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task CheckFileNameAndContentTypeConv() => Test(async (host) => + { + var id = "123"; + + await using var imageStream = File.OpenRead(SampleJpgPath); + var profileImage = new ProfileImageFileDetails(imageStream) + { + Filename = "hello.jpg", + ContentType = "image/jpg" + }; + var request = new MultiPartRequest(id, profileImage); + + var response = await new MultiPartClient(host, null).GetFormDataClient().CheckFileNameAndContentTypeAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task FileArrayAndBasic() => Test(async (host) => { @@ -78,6 +134,34 @@ public Task FileArrayAndBasic() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task FileArrayAndBasicConv() => Test(async (host) => + { + var id = "123"; + Address address = new Address("X"); + + await using var imageStream1 = File.OpenRead(SampleJpgPath); + var profileImage = new ProfileImageFileDetails(imageStream1) + { + Filename = "profileImage", + ContentType = "application/octet-stream" + }; + + await using var imageStream2 = File.OpenRead(SamplePngPath); + await using var imageStream3 = File.OpenRead(SamplePngPath); + var pictures = new List() + { + new(imageStream2) { Filename = "pictures", ContentType = "application/octet-stream" }, + new(imageStream3) { Filename = "pictures", ContentType = "application/octet-stream" } + }; + + var request = new ComplexPartsRequest(id, address, profileImage, pictures); + + var response = await new MultiPartClient(host, null).GetFormDataClient().FileArrayAndBasicAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task HttpPartsImageJpegContentType() => Test(async (host) => { @@ -93,6 +177,21 @@ public Task HttpPartsImageJpegContentType() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task HttpPartsImageJpegContentTypeConv() => Test(async (host) => + { + await using var imageStream = File.OpenRead(SampleJpgPath); + var profileImage = new FileSpecificContentType(imageStream, "hello.jpg"); + var request = new FileWithHttpPartSpecificContentTypeRequest(profileImage); + + var response = await new MultiPartClient(host, null).GetFormDataClient() + .GetFormDataHttpPartsClient() + .GetFormDataHttpPartsContentTypeClient() + .ImageJpegContentTypeAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task HttpPartsOptionalContentType() => Test(async (host) => { @@ -119,6 +218,36 @@ public Task HttpPartsOptionalContentType() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task HttpPartsOptionalContentTypeConv() => Test(async (host) => + { + await using var imageStream1 = File.OpenRead(SampleJpgPath); + var profileImage = new FileOptionalContentType(imageStream1, "hello.jpg"); + var request = new FileWithHttpPartOptionalContentTypeRequest(profileImage); + + var response = await new MultiPartClient(host, null).GetFormDataClient() + .GetFormDataHttpPartsClient() + .GetFormDataHttpPartsContentTypeClient() + .OptionalContentTypeAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + + using MultiPartFormDataBinaryContent contentWithContentType = new MultiPartFormDataBinaryContent(); + await using var imageStream2 = File.OpenRead(SampleJpgPath); + var profileImage2 = new FileOptionalContentType(imageStream2, "hello.jpg") + { + ContentType = "application/octet-stream" + }; + request = new FileWithHttpPartOptionalContentTypeRequest(profileImage2); + + response = await new MultiPartClient(host, null).GetFormDataClient() + .GetFormDataHttpPartsClient() + .GetFormDataHttpPartsContentTypeClient() + .OptionalContentTypeAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task HttpPartsRequiredContentType() => Test(async (host) => { @@ -134,6 +263,21 @@ public Task HttpPartsRequiredContentType() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task HttpPartsRequiredContentTypeConv() => Test(async (host) => + { + await using var imageStream = File.OpenRead(SampleJpgPath); + var profileImage = new FileRequiredMetaData(imageStream, "hello.jpg", "application/octet-stream"); + var request = new FileWithHttpPartRequiredContentTypeRequest(profileImage); + + var response = await new MultiPartClient(host, null).GetFormDataClient() + .GetFormDataHttpPartsClient() + .GetFormDataHttpPartsContentTypeClient() + .RequiredContentTypeAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task HttpPartsJsonArrayAndFileArray() => Test(async (host) => { @@ -170,6 +314,18 @@ public Task HttpPartsNonStringFloat() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task HttpPartsNonStringFloatAsync() => Test(async (host) => + { + var temperature = new FloatRequestTemperature(0.5f); + var request = new FloatRequest(temperature); + var response = await new MultiPartClient(host, null).GetFormDataClient() + .GetFormDataHttpPartsClient() + .GetFormDataHttpPartsNonStringClient() + .FloatAsync(request); + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task BinaryArrayParts() => Test(async (host) => { @@ -186,6 +342,24 @@ public Task BinaryArrayParts() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task BinaryArrayPartsConv() => Test(async (host) => + { + var id = "123"; + await using var imageStream1 = File.OpenRead(SamplePngPath); + await using var imageStream2 = File.OpenRead(SamplePngPath); + var pictures = new List() + { + new(imageStream1) { Filename = "pictures", ContentType = "application/octet-stream" }, + new(imageStream2) { Filename = "pictures", ContentType = "application/octet-stream" } + }; + var request = new BinaryArrayPartsRequest(id, pictures); + + var response = await new MultiPartClient(host, null).GetFormDataClient().BinaryArrayPartsAsync(request); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task AnonymousModel() => Test(async (host) => { @@ -198,14 +372,36 @@ public Task AnonymousModel() => Test(async (host) => Assert.AreEqual(204, response.GetRawResponse().Status); }); + [CadlRanchTest] + public Task AnonymousModelConv() => Test(async (host) => + { + await using var imageStream = File.OpenRead(SampleJpgPath); + var profileImageFileDetails = new ProfileImageFileDetails(imageStream) + { + Filename = "profileImage", + ContentType = "application/octet-stream" + }; + + var response = await new MultiPartClient(host, null).GetFormDataClient().AnonymousModelAsync(profileImageFileDetails); + + Assert.AreEqual(204, response.GetRawResponse().Status); + }); + [CadlRanchTest] public Task MultiBinaryPartsWithPicture() => MultiBinaryParts(true); + [CadlRanchTest] + public Task MultiBinaryPartsWithPictureConv() + => MultiBinaryPartsConv(true); [CadlRanchTest] public Task MultiBinaryPartsWithoutPicture() => MultiBinaryParts(false); + [CadlRanchTest] + public Task MultiBinaryPartsWithoutPictureConv() + => MultiBinaryPartsConv(false); + private Task MultiBinaryParts(bool hasPicture) => Test(async (host) => { using MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); @@ -219,5 +415,29 @@ private Task MultiBinaryParts(bool hasPicture) => Test(async (host) => var response = await new MultiPartClient(host, null).GetFormDataClient().MultiBinaryPartsAsync(content, content.ContentType, null); Assert.AreEqual(204, response.GetRawResponse().Status); }); + + private Task MultiBinaryPartsConv(bool hasPicture) => Test(async (host) => + { + await using var imageStream1 = File.OpenRead(SampleJpgPath); + var profileImage = new ProfileImageFileDetails(imageStream1) + { + Filename = "profileImage", + ContentType = "application/octet-stream" + }; + + await using var imageStream2 = File.OpenRead(SamplePngPath); + var picture = new PictureFileDetails(imageStream2) + { + Filename = "picture", + ContentType = "application/octet-stream" + }; + var request = new MultiBinaryPartsRequest(profileImage); + if (hasPicture) + { + request.Picture = picture; + } + var response = await new MultiPartClient(host, null).GetFormDataClient().MultiBinaryPartsAsync(request); + Assert.AreEqual(204, response.GetRawResponse().Status); + }); } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.RestClient.cs new file mode 100644 index 00000000000..e1b66b004a7 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.RestClient.cs @@ -0,0 +1,129 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Payload.MultiPart +{ + /// + public partial class FormData + { + private static PipelineMessageClassifier _pipelineMessageClassifier204; + + private static PipelineMessageClassifier PipelineMessageClassifier204 => _pipelineMessageClassifier204 = PipelineMessageClassifier.Create(stackalloc ushort[] { 204 }); + + internal PipelineMessage CreateBasicRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/mixed-parts", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateFileArrayAndBasicRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/complex-parts", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateJsonPartRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/json-part", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateBinaryArrayPartsRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/binary-array-parts", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateMultiBinaryPartsRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/multi-binary-parts", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateCheckFileNameAndContentTypeRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/check-filename-and-content-type", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateAnonymousModelRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/anonymous-model", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.cs index e6f6b6397e9..ea10d633fdc 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormData.cs @@ -2,46 +2,318 @@ #nullable disable +using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.IO; +using System.Threading; using System.Threading.Tasks; +using Payload.MultiPart.Models; namespace Payload.MultiPart { + /// public partial class FormData { - protected FormData() => throw null; + private readonly Uri _endpoint; + private FormDataHttpParts _cachedFormDataHttpParts; - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of FormData for mocking. + protected FormData() + { + } - public virtual ClientResult Basic(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + internal FormData(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } - public virtual Task BasicAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } - public virtual ClientResult FileArrayAndBasic(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual ClientResult Basic(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task FileArrayAndBasicAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateBasicRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } - public virtual ClientResult JsonPart(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual async Task BasicAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task JsonPartAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateBasicRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } - public virtual ClientResult BinaryArrayParts(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + // CUSTOM: Convenience method + public virtual ClientResult Basic(MultiPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); - public virtual Task BinaryArrayPartsAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return Basic(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } - public virtual ClientResult MultiBinaryParts(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + // CUSTOM: Convenience method + public virtual async Task BasicAsync(MultiPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); - public virtual Task MultiBinaryPartsAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await BasicAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + } - public virtual ClientResult CheckFileNameAndContentType(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual ClientResult FileArrayAndBasic(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task CheckFileNameAndContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateFileArrayAndBasicRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } - public virtual ClientResult AnonymousModel(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual async Task FileArrayAndBasicAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task AnonymousModelAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateFileArrayAndBasicRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } - public virtual FormDataHttpParts GetFormDataHttpPartsClient() => throw null; + // CUSTOM: Convenience method + public virtual ClientResult FileArrayAndBasic(ComplexPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return FileArrayAndBasic(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task FileArrayAndBasicAsync(ComplexPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await FileArrayAndBasicAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + public virtual ClientResult JsonPart(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateJsonPartRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task JsonPartAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateJsonPartRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual async Task JsonPartAsync(JsonPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = await JsonPartAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return result; + } + + // CUSTOM: Convenience method + public virtual ClientResult JsonPart(JsonPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = JsonPart(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return result; + } + + public virtual ClientResult BinaryArrayParts(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateBinaryArrayPartsRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task BinaryArrayPartsAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateBinaryArrayPartsRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual async Task BinaryArrayPartsAsync(BinaryArrayPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = await BinaryArrayPartsAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return result; + } + + // CUSTOM: Convenience method + public virtual ClientResult BinaryArrayParts(BinaryArrayPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = BinaryArrayParts(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return result; + } + + public virtual ClientResult MultiBinaryParts(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateMultiBinaryPartsRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task MultiBinaryPartsAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateMultiBinaryPartsRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual async Task MultiBinaryPartsAsync(MultiBinaryPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = await MultiBinaryPartsAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return result; + } + + // CUSTOM: Convenience method + public virtual ClientResult MultiBinaryParts(MultiBinaryPartsRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartBinaryBody(); + ClientResult result = MultiBinaryParts(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return result; + } + + public virtual ClientResult CheckFileNameAndContentType(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateCheckFileNameAndContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task CheckFileNameAndContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateCheckFileNameAndContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual async Task CheckFileNameAndContentTypeAsync(MultiPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + ClientResult result = await CheckFileNameAndContentTypeAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return result; + } + + // CUSTOM: Convenience method + public virtual ClientResult CheckFileNameAndContentType(MultiPartRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + ClientResult result = CheckFileNameAndContentType(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return result; + } + + public virtual ClientResult AnonymousModel(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateAnonymousModelRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task AnonymousModelAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateAnonymousModelRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual async Task AnonymousModelAsync(ProfileImageFileDetails profileImage, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + AnonymousModelRequest anonymousModelRequest = new AnonymousModelRequest(profileImage); + using MultiPartFormDataBinaryContent content = anonymousModelRequest.ToMultipartBinaryBody(); + ClientResult result = await AnonymousModelAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return result; + } + + // CUSTOM: Convenience method + public virtual ClientResult AnonymousModel(ProfileImageFileDetails profileImage, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + AnonymousModelRequest anonymousModelRequest = new AnonymousModelRequest(profileImage); + using MultiPartFormDataBinaryContent content = anonymousModelRequest.ToMultipartBinaryBody(); + ClientResult result = AnonymousModel(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return result; + } + + /// Initializes a new instance of FormDataHttpParts. + public virtual FormDataHttpParts GetFormDataHttpPartsClient() + { + return Volatile.Read(ref _cachedFormDataHttpParts) ?? Interlocked.CompareExchange(ref _cachedFormDataHttpParts, new FormDataHttpParts(Pipeline, _endpoint), null) ?? _cachedFormDataHttpParts; + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.RestClient.cs new file mode 100644 index 00000000000..83a40abfc8b --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.RestClient.cs @@ -0,0 +1,33 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Payload.MultiPart +{ + /// + public partial class FormDataHttpParts + { + private static PipelineMessageClassifier _pipelineMessageClassifier204; + + private static PipelineMessageClassifier PipelineMessageClassifier204 => _pipelineMessageClassifier204 = PipelineMessageClassifier.Create(stackalloc ushort[] { 204 }); + + internal PipelineMessage CreateJsonArrayAndFileArrayRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/complex-parts-with-httppart", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.cs index ea265b0c80a..da865e3deb0 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpParts.cs @@ -2,24 +2,84 @@ #nullable disable +using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Threading; using System.Threading.Tasks; +using Payload.MultiPart.Models; namespace Payload.MultiPart { + /// public partial class FormDataHttpParts { - protected FormDataHttpParts() => throw null; + private readonly Uri _endpoint; + private FormDataHttpPartsContentType _cachedFormDataHttpPartsContentType; + private FormDataHttpPartsNonString _cachedFormDataHttpPartsNonString; - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of FormDataHttpParts for mocking. + protected FormDataHttpParts() + { + } - public virtual ClientResult JsonArrayAndFileArray(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + internal FormDataHttpParts(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } - public virtual Task JsonArrayAndFileArrayAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } - public virtual FormDataHttpPartsContentType GetFormDataHttpPartsContentTypeClient() => throw null; + public virtual ClientResult JsonArrayAndFileArray(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual FormDataHttpPartsNonString GetFormDataHttpPartsNonStringClient() => throw null; + using PipelineMessage message = CreateJsonArrayAndFileArrayRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task JsonArrayAndFileArrayAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateJsonArrayAndFileArrayRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual ClientResult JsonArrayAndFileArray(ComplexHttpPartsModelRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return JsonArrayAndFileArray(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task JsonArrayAndFileArrayAsync(ComplexHttpPartsModelRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await JsonArrayAndFileArrayAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + } + + /// Initializes a new instance of FormDataHttpPartsContentType. + public virtual FormDataHttpPartsContentType GetFormDataHttpPartsContentTypeClient() + { + return Volatile.Read(ref _cachedFormDataHttpPartsContentType) ?? Interlocked.CompareExchange(ref _cachedFormDataHttpPartsContentType, new FormDataHttpPartsContentType(Pipeline, _endpoint), null) ?? _cachedFormDataHttpPartsContentType; + } + + /// Initializes a new instance of FormDataHttpPartsNonString. + public virtual FormDataHttpPartsNonString GetFormDataHttpPartsNonStringClient() + { + return Volatile.Read(ref _cachedFormDataHttpPartsNonString) ?? Interlocked.CompareExchange(ref _cachedFormDataHttpPartsNonString, new FormDataHttpPartsNonString(Pipeline, _endpoint), null) ?? _cachedFormDataHttpPartsNonString; + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.RestClient.cs new file mode 100644 index 00000000000..1a20ed6f476 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.RestClient.cs @@ -0,0 +1,65 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Payload.MultiPart +{ + /// + public partial class FormDataHttpPartsContentType + { + private static PipelineMessageClassifier _pipelineMessageClassifier204; + + private static PipelineMessageClassifier PipelineMessageClassifier204 => _pipelineMessageClassifier204 = PipelineMessageClassifier.Create(stackalloc ushort[] { 204 }); + + internal PipelineMessage CreateImageJpegContentTypeRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/check-filename-and-specific-content-type-with-httppart", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateRequiredContentTypeRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/check-filename-and-required-content-type-with-httppart", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateOptionalContentTypeRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/file-with-http-part-optional-content-type", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.cs index 480e3a74994..cbd2e24da76 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsContentType.cs @@ -2,28 +2,146 @@ #nullable disable +using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Threading; using System.Threading.Tasks; +using Payload.MultiPart.Models; namespace Payload.MultiPart { + /// public partial class FormDataHttpPartsContentType { - protected FormDataHttpPartsContentType() => throw null; + private readonly Uri _endpoint; - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of FormDataHttpPartsContentType for mocking. + protected FormDataHttpPartsContentType() + { + } - public virtual ClientResult ImageJpegContentType(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + internal FormDataHttpPartsContentType(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } - public virtual Task ImageJpegContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } - public virtual ClientResult RequiredContentType(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual ClientResult ImageJpegContentType(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task RequiredContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateImageJpegContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } - public virtual ClientResult OptionalContentType(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + public virtual async Task ImageJpegContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); - public virtual Task OptionalContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateImageJpegContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual ClientResult ImageJpegContentType(FileWithHttpPartSpecificContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return ImageJpegContentType(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task ImageJpegContentTypeAsync(FileWithHttpPartSpecificContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await ImageJpegContentTypeAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + } + + public virtual ClientResult RequiredContentType(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateRequiredContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task RequiredContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateRequiredContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual ClientResult RequiredContentType(FileWithHttpPartRequiredContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return RequiredContentType(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task RequiredContentTypeAsync(FileWithHttpPartRequiredContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await RequiredContentTypeAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + } + + public virtual ClientResult OptionalContentType(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateOptionalContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task OptionalContentTypeAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNullOrEmpty for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateOptionalContentTypeRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual ClientResult OptionalContentType(FileWithHttpPartOptionalContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return OptionalContentType(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task OptionalContentTypeAsync(FileWithHttpPartOptionalContentTypeRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await OptionalContentTypeAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.RestClient.cs new file mode 100644 index 00000000000..1feadedb5ee --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.RestClient.cs @@ -0,0 +1,33 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Payload.MultiPart +{ + /// + public partial class FormDataHttpPartsNonString + { + private static PipelineMessageClassifier _pipelineMessageClassifier204; + + private static PipelineMessageClassifier PipelineMessageClassifier204 => _pipelineMessageClassifier204 = PipelineMessageClassifier.Create(stackalloc ushort[] { 204 }); + + internal PipelineMessage CreateFloatRequest(BinaryContent content, string contentType, RequestOptions options) + { + PipelineMessage message = Pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier204; + PipelineRequest request = message.Request; + request.Method = "POST"; + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/multipart/form-data/non-string-float", false); + request.Uri = uri.ToUri(); + request.Headers.Set("Content-Type", contentType); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.cs index 7774f553662..28823d73b7a 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/FormDataHttpPartsNonString.cs @@ -2,20 +2,70 @@ #nullable disable +using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Threading; using System.Threading.Tasks; +using Payload.MultiPart.Models; namespace Payload.MultiPart { + /// public partial class FormDataHttpPartsNonString { - protected FormDataHttpPartsNonString() => throw null; + private readonly Uri _endpoint; - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of FormDataHttpPartsNonString for mocking. + protected FormDataHttpPartsNonString() + { + } - public virtual ClientResult Float(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + internal FormDataHttpPartsNonString(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } - public virtual Task FloatAsync(BinaryContent content, string contentType, RequestOptions options = null) => throw null; + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + public virtual ClientResult Float(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateFloatRequest(content, contentType, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public virtual async Task FloatAsync(BinaryContent content, string contentType, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + // CUSTOM: AssertNotNull for required contentType + Argument.AssertNotNull(contentType, nameof(contentType)); + + using PipelineMessage message = CreateFloatRequest(content, contentType, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + // CUSTOM: Convenience method + public virtual ClientResult Float(FloatRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return Float(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } + + // CUSTOM: Convenience method + public virtual async Task FloatAsync(FloatRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + using MultiPartFormDataBinaryContent content = body.ToMultipartContent(); + return await FloatAsync(content, content.ContentType, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Argument.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Argument.cs new file mode 100644 index 00000000000..4c61536c40d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Argument.cs @@ -0,0 +1,126 @@ +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Payload.MultiPart +{ + internal static partial class Argument + { + public static void AssertNotNull(T value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + } + + public static void AssertNotNull(T? value, string name) + where T : struct + { + if (!value.HasValue) + { + throw new ArgumentNullException(name); + } + } + + public static void AssertNotNullOrEmpty(IEnumerable value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + if (value is ICollection collectionOfT && collectionOfT.Count == 0) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + if (value is ICollection collection && collection.Count == 0) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + using IEnumerator e = value.GetEnumerator(); + if (!e.MoveNext()) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + } + + public static void AssertNotNullOrEmpty(string value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + if (value.Length == 0) + { + throw new ArgumentException("Value cannot be an empty string.", name); + } + } + + public static void AssertNotNullOrWhiteSpace(string value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Value cannot be empty or contain only white-space characters.", name); + } + } + + public static void AssertNotDefault(ref T value, string name) + where T : struct, IEquatable + { + if (value.Equals(default)) + { + throw new ArgumentException("Value cannot be empty.", name); + } + } + + public static void AssertInRange(T value, T minimum, T maximum, string name) + where T : notnull, IComparable + { + if (minimum.CompareTo(value) > 0) + { + throw new ArgumentOutOfRangeException(name, "Value is less than the minimum allowed."); + } + if (maximum.CompareTo(value) < 0) + { + throw new ArgumentOutOfRangeException(name, "Value is greater than the maximum allowed."); + } + } + + public static void AssertEnumDefined(Type enumType, object value, string name) + { + if (!Enum.IsDefined(enumType, value)) + { + throw new ArgumentException($"Value not defined for {enumType.FullName}.", name); + } + } + + public static T CheckNotNull(T value, string name) + where T : class + { + AssertNotNull(value, name); + return value; + } + + public static string CheckNotNullOrEmpty(string value, string name) + { + AssertNotNullOrEmpty(value, name); + return value; + } + + public static void AssertNull(T value, string name, string message = null) + { + if (value != null) + { + throw new ArgumentException(message ?? "Value must be null.", name); + } + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientPipelineExtensions.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientPipelineExtensions.cs new file mode 100644 index 00000000000..0227aab864c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientPipelineExtensions.cs @@ -0,0 +1,67 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +namespace Payload.MultiPart +{ + internal static partial class ClientPipelineExtensions + { + public static async ValueTask ProcessMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + await pipeline.SendAsync(message).ConfigureAwait(false); + + if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) + { + throw await ClientResultException.CreateAsync(message.Response).ConfigureAwait(false); + } + + PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); + return response; + } + + public static PipelineResponse ProcessMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + pipeline.Send(message); + + if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) + { + throw new ClientResultException(message.Response); + } + + PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); + return response; + } + + public static async ValueTask> ProcessHeadAsBoolMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + PipelineResponse response = await pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false); + switch (response.Status) + { + case >= 200 and < 300: + return ClientResult.FromValue(true, response); + case >= 400 and < 500: + return ClientResult.FromValue(false, response); + default: + return new ErrorResult(response, new ClientResultException(response)); + } + } + + public static ClientResult ProcessHeadAsBoolMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + PipelineResponse response = pipeline.ProcessMessage(message, options); + switch (response.Status) + { + case >= 200 and < 300: + return ClientResult.FromValue(true, response); + case >= 400 and < 500: + return ClientResult.FromValue(false, response); + default: + return new ErrorResult(response, new ClientResultException(response)); + } + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientUriBuilder.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientUriBuilder.cs new file mode 100644 index 00000000000..1d08f02e78c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ClientUriBuilder.cs @@ -0,0 +1,131 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Payload.MultiPart +{ + internal partial class ClientUriBuilder + { + private UriBuilder _uriBuilder; + private StringBuilder _pathBuilder; + private StringBuilder _queryBuilder; + + public ClientUriBuilder() + { + } + + private UriBuilder UriBuilder => _uriBuilder ??= new UriBuilder(); + + private StringBuilder PathBuilder => _pathBuilder ??= new StringBuilder(UriBuilder.Path); + + private StringBuilder QueryBuilder => _queryBuilder ??= new StringBuilder(UriBuilder.Query); + + public void Reset(Uri uri) + { + _uriBuilder = new UriBuilder(uri); + _pathBuilder = new StringBuilder(UriBuilder.Path); + _queryBuilder = new StringBuilder(UriBuilder.Query); + } + + public void AppendPath(string value, bool escape) + { + if (escape) + { + value = Uri.EscapeDataString(value); + } + if (PathBuilder.Length > 0 && PathBuilder[PathBuilder.Length - 1] == '/' && value[0] == '/') + { + PathBuilder.Remove(PathBuilder.Length - 1, 1); + } + PathBuilder.Append(value); + UriBuilder.Path = PathBuilder.ToString(); + } + + public void AppendPath(bool value, bool escape = false) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(float value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(double value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(int value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(byte[] value, string format, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(DateTimeOffset value, string format, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(TimeSpan value, string format, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(Guid value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(long value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPathDelimited(IEnumerable value, string delimiter, string format = null, bool escape = true) + { + delimiter ??= ","; + IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); + AppendPath(string.Join(delimiter, stringValues), escape); + } + + public void AppendQuery(string name, string value, bool escape) + { + if (QueryBuilder.Length > 0) + { + QueryBuilder.Append('&'); + } + if (escape) + { + value = Uri.EscapeDataString(value); + } + QueryBuilder.Append(name); + QueryBuilder.Append('='); + QueryBuilder.Append(value); + } + + public void AppendQuery(string name, bool value, bool escape = false) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, float value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, DateTimeOffset value, string format, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, TimeSpan value, string format, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, double value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, decimal value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, int value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, long value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, TimeSpan value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, byte[] value, string format, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, Guid value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQueryDelimited(string name, IEnumerable value, string delimiter, string format = null, bool escape = true) + { + delimiter ??= ","; + IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); + AppendQuery(name, string.Join(delimiter, stringValues), escape); + } + + public Uri ToUri() + { + if (_pathBuilder != null) + { + UriBuilder.Path = _pathBuilder.ToString(); + } + if (_queryBuilder != null) + { + UriBuilder.Query = _queryBuilder.ToString(); + } + return UriBuilder.Uri; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ErrorResult.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ErrorResult.cs new file mode 100644 index 00000000000..b7d4ecb033c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ErrorResult.cs @@ -0,0 +1,23 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Payload.MultiPart +{ + internal partial class ErrorResult : ClientResult + { + private readonly PipelineResponse _response; + private readonly ClientResultException _exception; + + public ErrorResult(PipelineResponse response, ClientResultException exception) : base(default, response) + { + _response = response; + _exception = exception; + } + + public override T Value => throw _exception; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ModelSerializationExtensions.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ModelSerializationExtensions.cs new file mode 100644 index 00000000000..5204bccf2e5 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/ModelSerializationExtensions.cs @@ -0,0 +1,251 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Text.Json; + +namespace Payload.MultiPart +{ + internal static partial class ModelSerializationExtensions + { + internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W"); + + public static object GetObject(this JsonElement element) + { + switch (element.ValueKind) + { + case JsonValueKind.String: + return element.GetString(); + case JsonValueKind.Number: + if (element.TryGetInt32(out int intValue)) + { + return intValue; + } + if (element.TryGetInt64(out long longValue)) + { + return longValue; + } + return element.GetDouble(); + case JsonValueKind.True: + return true; + case JsonValueKind.False: + return false; + case JsonValueKind.Undefined: + case JsonValueKind.Null: + return null; + case JsonValueKind.Object: + Dictionary dictionary = new Dictionary(); + foreach (var jsonProperty in element.EnumerateObject()) + { + dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); + } + return dictionary; + case JsonValueKind.Array: + List list = new List(); + foreach (var item in element.EnumerateArray()) + { + list.Add(item.GetObject()); + } + return list.ToArray(); + default: + throw new NotSupportedException($"Not supported value kind {element.ValueKind}"); + } + } + + public static byte[] GetBytesFromBase64(this JsonElement element, string format) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + + return format switch + { + "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()), + "D" => element.GetBytesFromBase64(), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + } + + public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch + { + "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()), + _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format) + }; + + public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format); + + public static char GetChar(this JsonElement element) + { + if (element.ValueKind == JsonValueKind.String) + { + string text = element.GetString(); + if (text == null || text.Length != 1) + { + throw new NotSupportedException($"Cannot convert \"{text}\" to a char"); + } + return text[0]; + } + else + { + throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char"); + } + } + + [Conditional("DEBUG")] + public static void ThrowNonNullablePropertyIsNull(this JsonProperty @property) + { + throw new JsonException($"A property '{@property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build"); + } + + public static string GetRequiredString(this JsonElement element) + { + string value = element.GetString(); + if (value == null) + { + throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'."); + } + return value; + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, char value) + { + writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); + } + + public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + switch (format) + { + case "U": + writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value)); + break; + case "D": + writer.WriteBase64StringValue(value); + break; + default: + throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)); + } + } + + public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + if (format != "U") + { + throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number."); + } + writer.WriteNumberValue(value.ToUnixTimeSeconds()); + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null) + { + switch (value) + { + case null: + writer.WriteNullValue(); + break; + case IJsonModel jsonModel: + jsonModel.Write(writer, options ?? WireOptions); + break; + case byte[] bytes: + writer.WriteBase64StringValue(bytes); + break; + case BinaryData bytes0: + writer.WriteBase64StringValue(bytes0); + break; + case JsonElement json: + json.WriteTo(writer); + break; + case int i: + writer.WriteNumberValue(i); + break; + case decimal d: + writer.WriteNumberValue(d); + break; + case double d0: + if (double.IsNaN(d0)) + { + writer.WriteStringValue("NaN"); + } + else + { + writer.WriteNumberValue(d0); + } + break; + case float f: + writer.WriteNumberValue(f); + break; + case long l: + writer.WriteNumberValue(l); + break; + case string s: + writer.WriteStringValue(s); + break; + case bool b: + writer.WriteBooleanValue(b); + break; + case Guid g: + writer.WriteStringValue(g); + break; + case DateTimeOffset dateTimeOffset: + writer.WriteStringValue(dateTimeOffset, "O"); + break; + case DateTime dateTime: + writer.WriteStringValue(dateTime, "O"); + break; + case IEnumerable> enumerable: + writer.WriteStartObject(); + foreach (var pair in enumerable) + { + writer.WritePropertyName(pair.Key); + writer.WriteObjectValue(pair.Value, options); + } + writer.WriteEndObject(); + break; + case IEnumerable objectEnumerable: + writer.WriteStartArray(); + foreach (var item in objectEnumerable) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + break; + case TimeSpan timeSpan: + writer.WriteStringValue(timeSpan, "P"); + break; + default: + throw new NotSupportedException($"Not supported type {value.GetType()}"); + } + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null) + { + writer.WriteObjectValue(value, options); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/MultiPartFormDataBinaryContent.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/MultiPartFormDataBinaryContent.cs index 70bc3dbd765..e0bc3cef3b5 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/MultiPartFormDataBinaryContent.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/MultiPartFormDataBinaryContent.cs @@ -1,50 +1,278 @@ -// - #nullable disable using System; using System.ClientModel; +using System.Diagnostics; +using System.Globalization; using System.IO; using System.Net.Http; +using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; -namespace Payload.MultiPart +namespace Payload.MultiPart; + +internal partial class MultiPartFormDataBinaryContent : BinaryContent { - internal partial class MultiPartFormDataBinaryContent : BinaryContent + private readonly MultipartFormDataContent _multipartContent; + + private const int BoundaryLength = 70; + private const string BoundaryValues = "0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; + + public MultiPartFormDataBinaryContent() + { + _multipartContent = new MultipartFormDataContent(CreateBoundary()); + } + + public string ContentType + { + get + { + Debug.Assert(_multipartContent.Headers.ContentType is not null); + + return _multipartContent.Headers.ContentType!.ToString(); + } + } + + internal HttpContent HttpContent => _multipartContent; + + // CUSTOM: Add optional content type parameter to the Add method. + + public void Add(Stream stream, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(stream, nameof(stream)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + StreamContent content = new(stream); + if (contentType is not null) + { + content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(content, name, fileName); + } + + public void Add(string content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + StringContent stringContent = new(content); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + + Add(stringContent, name, fileName); + } + + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(int content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + string value = content.ToString("G", CultureInfo.InvariantCulture); + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } + + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(long content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + string value = content.ToString("G", CultureInfo.InvariantCulture); + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } + + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(float content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + string value = content.ToString("G", CultureInfo.InvariantCulture); + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } + + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(double content, string name, string fileName = default, string contentType = default) { - public MultiPartFormDataBinaryContent() => throw null; + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + + string value = content.ToString("G", CultureInfo.InvariantCulture); + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } - public string ContentType => throw null; + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(decimal content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); - public void Add(string content, string name, string filename = default, string contentType = default) => throw null; + string value = content.ToString("G", CultureInfo.InvariantCulture); + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } - public void Add(int content, string name, string filename = default, string contentType = default) => throw null; + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(bool content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); - public void Add(long content, string name, string filename = default, string contentType = default) => throw null; + string value = content ? "true" : "false"; + StringContent stringContent = new(value); + if (contentType is not null) + { + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(stringContent, name, fileName); + } - public void Add(float content, string name, string filename = default, string contentType = default) => throw null; + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(byte[] content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); + var byteArrayContent = new ByteArrayContent(content); + if (contentType is not null) + { + byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } - public void Add(double content, string name, string filename = default, string contentType = default) => throw null; + Add(byteArrayContent, name, fileName); + } - public void Add(decimal content, string name, string filename = default, string contentType = default) => throw null; + // CUSTOM: Add optional content type parameter to the Add method. + public void Add(BinaryData content, string name, string fileName = default, string contentType = default) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNullOrEmpty(name, nameof(name)); - public void Add(bool content, string name, string filename = default, string contentType = default) => throw null; + ByteArrayContent byteArrayContent = new(content.ToArray()); + if (contentType is not null) + { + byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(byteArrayContent, name, fileName); + } - public void Add(Stream content, string name, string filename = default, string contentType = default) => throw null; + private void Add(HttpContent content, string name, string fileName) + { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNull(name, nameof(name)); - public void Add(byte[] content, string name, string filename = default, string contentType = default) => throw null; + if (fileName is not null) + { + _multipartContent.Add(content, name, fileName); + } + else + { + _multipartContent.Add(content, name); + } + } - public void Add(BinaryData content, string name, string filename = default, string contentType = default) => throw null; +#if NET6_0_OR_GREATER + private static string CreateBoundary() => + string.Create(BoundaryLength, 0, (chars, _) => + { + Span random = stackalloc byte[BoundaryLength]; + Random.Shared.NextBytes(random); - public static void AddContentTypeHeader(HttpContent content, string contentType) => throw null; + for (int i = 0; i < chars.Length; i++) + { + chars[i] = BoundaryValues[random[i] % BoundaryValues.Length]; + } + }); +#else + private static readonly Random _random = new(); - public override bool TryComputeLength(out long length) => throw null; + private static string CreateBoundary() + { + Span chars = stackalloc char[BoundaryLength]; - public override void WriteTo(Stream stream, CancellationToken cancellationToken = default) => throw null; + byte[] random = new byte[BoundaryLength]; + lock (_random) + { + _random.NextBytes(random); + } - public override Task WriteToAsync(Stream stream, CancellationToken cancellationToken = default) => throw null; + // Instead of `% BoundaryValues.Length` as is used above, use a mask to achieve the same result. + // `% BoundaryValues.Length` is optimized to the equivalent on .NET Core but not on .NET Framework. + const int Mask = 255 >> 2; + Debug.Assert(BoundaryValues.Length - 1 == Mask); - public override void Dispose() => throw null; + for (int i = 0; i < chars.Length; i++) + { + chars[i] = BoundaryValues[random[i] & Mask]; + } + + return chars.ToString(); + } +#endif + + public override bool TryComputeLength(out long length) + { + // We can't call the protected method on HttpContent + + if (_multipartContent.Headers.ContentLength is long contentLength) + { + length = contentLength; + return true; + } + + length = 0; + return false; + } + + public override void WriteTo(Stream stream, CancellationToken cancellationToken = default) + { +#if NET5_0_OR_GREATER + _multipartContent.CopyTo(stream, default, cancellationToken); +#else + // TODO: polyfill sync-over-async for netstandard2.0 for Azure clients. + // Tracked by https://github.com/Azure/azure-sdk-for-net/issues/42674 + _multipartContent.CopyToAsync(stream).GetAwaiter().GetResult(); +#endif + } + + public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken = default) + { +#if NET5_0_OR_GREATER + await _multipartContent.CopyToAsync(stream, cancellationToken).ConfigureAwait(false); +#else + await _multipartContent.CopyToAsync(stream).ConfigureAwait(false); +#endif + } + + public override void Dispose() + { + _multipartContent.Dispose(); } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Optional.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Optional.cs new file mode 100644 index 00000000000..e520ee8100c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/Optional.cs @@ -0,0 +1,47 @@ +// + +#nullable disable + +using System.Text.Json; + +namespace Payload.MultiPart +{ + internal static partial class Optional + { + //public static bool IsCollectionDefined(IEnumerable collection) + //{ + // return !(collection is ChangeTrackingList changeTrackingList && changeTrackingList.IsUndefined); + //} + + //public static bool IsCollectionDefined(IDictionary collection) + //{ + // return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined); + //} + + //public static bool IsCollectionDefined(IReadOnlyDictionary collection) + //{ + // return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined); + //} + + public static bool IsDefined(T? value) + where T : struct + { + return value.HasValue; + } + + public static bool IsDefined(object value) + { + return value != null; + } + + public static bool IsDefined(string value) + { + return value != null; + } + + public static bool IsDefined(JsonElement value) + { + return value.ValueKind != JsonValueKind.Undefined; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/TypeFormatters.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/TypeFormatters.cs new file mode 100644 index 00000000000..d20f9511ea2 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Internal/TypeFormatters.cs @@ -0,0 +1,150 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Xml; + +namespace Payload.MultiPart +{ + internal static partial class TypeFormatters + { + private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ"; + public const string DefaultNumberFormat = "G"; + + public static string ToString(bool value) => value ? "true" : "false"; + + public static string ToString(DateTime value, string format) => value.Kind switch + { + DateTimeKind.Utc => ToString((DateTimeOffset)value, format), + _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") + }; + + public static string ToString(DateTimeOffset value, string format) => format switch + { + "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), + "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "R" => value.ToString("r", CultureInfo.InvariantCulture), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(TimeSpan value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToString(value), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(byte[] value, string format) => format switch + { + "U" => ToBase64UrlString(value), + "D" => Convert.ToBase64String(value), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + + public static string ToBase64UrlString(byte[] value) + { + int numWholeOrPartialInputBlocks = checked (value.Length + 2) / 3; + int size = checked (numWholeOrPartialInputBlocks * 4); + char[] output = new char[size]; + + int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0); + + int i = 0; + for (; i < numBase64Chars; i++) + { + char ch = output[i]; + if (ch == '+') + { + output[i] = '-'; + } + else + { + if (ch == '/') + { + output[i] = '_'; + } + else + { + if (ch == '=') + { + break; + } + } + } + } + + return new string(output, 0, i); + } + + public static byte[] FromBase64UrlString(string value) + { + int paddingCharsToAdd = (value.Length % 4) switch + { + 0 => 0, + 2 => 2, + 3 => 1, + _ => throw new InvalidOperationException("Malformed input") + }; + char[] output = new char[(value.Length + paddingCharsToAdd)]; + int i = 0; + for (; i < value.Length; i++) + { + char ch = value[i]; + if (ch == '-') + { + output[i] = '+'; + } + else + { + if (ch == '_') + { + output[i] = '/'; + } + else + { + output[i] = ch; + } + } + } + + for (; i < output.Length; i++) + { + output[i] = '='; + } + + return Convert.FromBase64CharArray(output, 0, output.Length); + } + + public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch + { + "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)), + _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) + }; + + public static TimeSpan ParseTimeSpan(string value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToTimeSpan(value), + _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture) + }; + + public static string ConvertToString(object value, string format = null) => value switch + { + null => "null", + string s => s, + bool b => ToString(b), + int or float or double or long or decimal => ((IFormattable)value).ToString(DefaultNumberFormat, CultureInfo.InvariantCulture), + byte[] b0 when format != null => ToString(b0, format), + IEnumerable s0 => string.Join(",", s0), + DateTimeOffset dateTime when format != null => ToString(dateTime, format), + TimeSpan timeSpan when format != null => ToString(timeSpan, format), + TimeSpan timeSpan0 => System.Xml.XmlConvert.ToString(timeSpan0), + Guid guid => guid.ToString(), + BinaryData binaryData => ConvertToString(binaryData.ToArray(), format), + _ => value.ToString() + }; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.Serialization.cs new file mode 100644 index 00000000000..a7242bf0d9e --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.Serialization.cs @@ -0,0 +1,141 @@ +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Payload.MultiPart.Models +{ + public partial class Address : IJsonModel
+ { + internal Address() + { + + } + + void IJsonModel
.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel
)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Address)} does not support writing '{format}' format."); + } + + writer.WritePropertyName("city"u8); + writer.WriteStringValue(City); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + Address IJsonModel
.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual Address JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel
)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Address)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAddress(document.RootElement, options); + } + + internal static Address DeserializeAddress(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string city = default; + IDictionary additionalBinaryDataProperties = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("city"u8)) + { + city = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + return new Address(city, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel
.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel
)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Address)} does not support writing '{options.Format}' format."); + } + } + + Address IPersistableModel
.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual Address PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel
)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAddress(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Address)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel
.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(Address address) + { + if (address == null) + { + return null; + } + return BinaryContent.Create(address, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Address(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeAddress(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.cs new file mode 100644 index 00000000000..9664a6784f7 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/Address.cs @@ -0,0 +1,27 @@ +#nullable disable + +using System.Collections.Generic; +using System; + +namespace Payload.MultiPart.Models +{ + public partial class Address + { + private protected readonly IDictionary _additionalBinaryDataProperties; + + public Address(string city) + { + Argument.AssertNotNull(city, nameof(city)); + + City = city; + } + + internal Address(string city, IDictionary additionalBinaryDataProperties) + { + City = city; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public string City { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.Serialization.cs new file mode 100644 index 00000000000..e7deb48bfbd --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.Serialization.cs @@ -0,0 +1,24 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; + +namespace Payload.MultiPart.Models +{ + internal partial class AnonymousModelRequest + { + internal MultiPartFormDataBinaryContent ToMultipartBinaryBody() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.cs new file mode 100644 index 00000000000..c7af824a988 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/AnonymousModelRequest.cs @@ -0,0 +1,28 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.IO; + +namespace Payload.MultiPart.Models +{ + /// The AnonymousModelRequest. + internal partial class AnonymousModelRequest + { + + /// Initializes a new instance of . + /// + /// is null. + public AnonymousModelRequest(ProfileImageFileDetails profileImage) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + ProfileImage = profileImage; + } + + /// Gets the profile image. + public ProfileImageFileDetails ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.Serialization.cs new file mode 100644 index 00000000000..03cb959f910 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.Serialization.cs @@ -0,0 +1,21 @@ +// + +#nullable disable + +namespace Payload.MultiPart.Models +{ + public partial class BinaryArrayPartsRequest + { + internal virtual MultiPartFormDataBinaryContent ToMultipartBinaryBody() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + content.Add(Id, "id"); + + foreach (var picture in Pictures) + { + content.Add(picture.Contents, "pictures", picture.Filename, picture.ContentType); + } + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.cs new file mode 100644 index 00000000000..e9f2f4030c2 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/BinaryArrayPartsRequest.cs @@ -0,0 +1,29 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Payload.MultiPart.Models +{ + /// The BinaryArrayPartsRequest. + public partial class BinaryArrayPartsRequest + { + public BinaryArrayPartsRequest(string id, IEnumerable pictures) + { + Argument.AssertNotNull(id, nameof(id)); + Argument.AssertNotNull(pictures, nameof(pictures)); + + Id = id; + Pictures = pictures.ToList(); + } + + /// Gets the id. + public string Id { get; } + /// Gets the pictures. + public IList Pictures { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.Serialization.cs new file mode 100644 index 00000000000..b8794287366 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.Serialization.cs @@ -0,0 +1,28 @@ +using System.ClientModel.Primitives; + +namespace Payload.MultiPart.Models +{ + public partial class ComplexHttpPartsModelRequest + { + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(Id, "id"); + content.Add(ModelReaderWriter.Write(Address, ModelSerializationExtensions.WireOptions), "address"); + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + + foreach (Address item in PreviousAddresses) + { + content.Add(ModelReaderWriter.Write(item, ModelSerializationExtensions.WireOptions), "previousAddresses"); + } + + foreach (var picture in Pictures) + { + content.Add(picture.Contents, "pictures", picture.Filename, picture.ContentType); + } + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.cs new file mode 100644 index 00000000000..2443fd159a3 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexHttpPartsModelRequest.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Payload.MultiPart.Models +{ + public partial class ComplexHttpPartsModelRequest + { + public ComplexHttpPartsModelRequest(string id, Address address, FileRequiredMetaData profileImage, IEnumerable
previousAddresses, IEnumerable pictures) + { + Argument.AssertNotNull(id, nameof(id)); + Argument.AssertNotNull(address, nameof(address)); + Argument.AssertNotNull(profileImage, nameof(profileImage)); + Argument.AssertNotNull(previousAddresses, nameof(previousAddresses)); + Argument.AssertNotNull(pictures, nameof(pictures)); + + Id = id; + Address = address; + ProfileImage = profileImage; + PreviousAddresses = previousAddresses.ToList(); + Pictures = pictures.ToList(); + } + + public string Id { get; } + public Address Address { get; } + public FileRequiredMetaData ProfileImage { get; } + public IList
PreviousAddresses { get; } + public IList Pictures { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.Serialization.cs new file mode 100644 index 00000000000..af6a08dbb99 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.Serialization.cs @@ -0,0 +1,27 @@ +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text; + +namespace Payload.MultiPart.Models +{ + public partial class ComplexPartsRequest + { + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(Id, "id"); + content.Add(ModelReaderWriter.Write(Address, ModelSerializationExtensions.WireOptions), "address"); + content.Add(ProfileImageFileDetails.Contents, "profileImage", ProfileImageFileDetails.Filename, ProfileImageFileDetails.ContentType); + + + foreach (var picture in Pictures) + { + content.Add(picture.Contents, "pictures", picture.Filename, picture.ContentType); + } + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.cs new file mode 100644 index 00000000000..e82ab8ee9e6 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ComplexPartsRequest.cs @@ -0,0 +1,32 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Payload.MultiPart.Models +{ + public partial class ComplexPartsRequest + { + public ComplexPartsRequest(string id, Address address, ProfileImageFileDetails profileImage, IEnumerable pictures) + { + Argument.AssertNotNull(id, nameof(id)); + Argument.AssertNotNull(address, nameof(address)); + Argument.AssertNotNull(profileImage, nameof(profileImage)); + Argument.AssertNotNull(pictures, nameof(pictures)); + + Id = id; + Address = address; + ProfileImageFileDetails = profileImage; + Pictures = pictures.ToList(); + } + + public string Id { get; } + public Address Address { get; } + public ProfileImageFileDetails ProfileImageFileDetails { get; } + public IList Pictures { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileOptionalContentType.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileOptionalContentType.cs new file mode 100644 index 00000000000..ab75914796b --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileOptionalContentType.cs @@ -0,0 +1,22 @@ +#nullable disable + +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class FileOptionalContentType + { + public FileOptionalContentType(Stream contents, string filename) + { + Argument.AssertNotNull(contents, nameof(contents)); + Argument.AssertNotNull(filename, nameof(filename)); + + Contents = contents; + Filename = filename; + } + + public Stream Contents { get; } + public string Filename { get; } + public string ContentType { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileRequiredMetaData.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileRequiredMetaData.cs new file mode 100644 index 00000000000..e3d6dc6cf26 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileRequiredMetaData.cs @@ -0,0 +1,22 @@ +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class FileRequiredMetaData + { + public FileRequiredMetaData(Stream contents, string filename, string contentType) + { + Argument.AssertNotNull(contents, nameof(contents)); + Argument.AssertNotNull(filename, nameof(filename)); + Argument.AssertNotNull(contentType, nameof(contentType)); + + Contents = contents; + Filename = filename; + ContentType = contentType; + } + + public Stream Contents { get; } + public string Filename { get; } + public string ContentType { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentType.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentType.cs new file mode 100644 index 00000000000..df91f3fb361 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentType.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class FileSpecificContentType + { + public FileSpecificContentType(Stream contents, string filename) + { + Argument.AssertNotNull(contents, nameof(contents)); + Argument.AssertNotNull(filename, nameof(filename)); + + Contents = contents; + Filename = filename; + } + + public Stream Contents { get; } + public string Filename { get; } + public FileSpecificContentTypeContentType ContentType { get; } = "image/jpg"; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentTypeContentType.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentTypeContentType.cs new file mode 100644 index 00000000000..cdca0003af5 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileSpecificContentTypeContentType.cs @@ -0,0 +1,57 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Payload.MultiPart.Models +{ + public readonly partial struct FileSpecificContentTypeContentType : IEquatable + { + private readonly string _value; + + private const string ImageJpgValue = "image/jpg"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public FileSpecificContentTypeContentType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// accept. + public static FileSpecificContentTypeContentType ImageJpg { get; } = new FileSpecificContentTypeContentType(ImageJpgValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(FileSpecificContentTypeContentType left, FileSpecificContentTypeContentType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(FileSpecificContentTypeContentType left, FileSpecificContentTypeContentType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator FileSpecificContentTypeContentType(string value) => new FileSpecificContentTypeContentType(value); + + /// The object to compare. + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is FileSpecificContentTypeContentType other && Equals(other); + + /// The instance to compare. + public bool Equals(FileSpecificContentTypeContentType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.Serialization.cs new file mode 100644 index 00000000000..0eeaf115bf7 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.Serialization.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartOptionalContentTypeRequest + { + + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.cs new file mode 100644 index 00000000000..47cc5ca5e49 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartOptionalContentTypeRequest.cs @@ -0,0 +1,15 @@ +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartOptionalContentTypeRequest + { + public FileWithHttpPartOptionalContentTypeRequest(FileOptionalContentType profileImage) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + ProfileImage = profileImage; + } + + /// Gets the profile image. + public FileOptionalContentType ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.Serialization.cs new file mode 100644 index 00000000000..4241efceabf --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.Serialization.cs @@ -0,0 +1,15 @@ +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartRequiredContentTypeRequest + { + + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.cs new file mode 100644 index 00000000000..9ef499e14ab --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartRequiredContentTypeRequest.cs @@ -0,0 +1,15 @@ +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartRequiredContentTypeRequest + { + public FileWithHttpPartRequiredContentTypeRequest(FileRequiredMetaData profileImage) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + ProfileImage = profileImage; + } + + /// Gets the profile image. + public FileRequiredMetaData ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.Serialization.cs new file mode 100644 index 00000000000..2343cbcb05c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.Serialization.cs @@ -0,0 +1,17 @@ +using System; + +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartSpecificContentTypeRequest + { + + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType.ToString()); + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.cs new file mode 100644 index 00000000000..242a0646316 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FileWithHttpPartSpecificContentTypeRequest.cs @@ -0,0 +1,17 @@ +using System; + +namespace Payload.MultiPart.Models +{ + public partial class FileWithHttpPartSpecificContentTypeRequest + { + public FileWithHttpPartSpecificContentTypeRequest(FileSpecificContentType profileImage) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + ProfileImage = profileImage; + } + + /// Gets the profile image. + public FileSpecificContentType ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.Serialization.cs new file mode 100644 index 00000000000..c7dfc5e371d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.Serialization.cs @@ -0,0 +1,22 @@ +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; + +namespace Payload.MultiPart.Models +{ + public partial class FloatRequest + { + + internal virtual MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + content.Add(Temperature.Temperature, "temperature", contentType: Temperature.ContentType.ToString()); + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.cs new file mode 100644 index 00000000000..da83843d4e5 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequest.cs @@ -0,0 +1,16 @@ +// + +#nullable disable + +namespace Payload.MultiPart.Models +{ + public partial class FloatRequest + { + public FloatRequest(FloatRequestTemperature temperature) + { + Temperature = temperature; + } + + public FloatRequestTemperature Temperature { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperature.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperature.cs new file mode 100644 index 00000000000..16731056291 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperature.cs @@ -0,0 +1,19 @@ +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Payload.MultiPart.Models +{ + public partial class FloatRequestTemperature + { + public FloatRequestTemperature(double temperature) + { + Temperature = temperature; + } + + public double Temperature { get; } + + public FloatRequestTemperatureContentType ContentType { get; } = "text/plain"; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperatureContentType.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperatureContentType.cs new file mode 100644 index 00000000000..ae5cf34e57f --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/FloatRequestTemperatureContentType.cs @@ -0,0 +1,54 @@ +#nullable disable + +using System; +using System.ComponentModel; + +namespace Payload.MultiPart.Models +{ + public readonly partial struct FloatRequestTemperatureContentType : IEquatable + { + private readonly string _value; + + private const string TextPlainValue = "text/plain"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public FloatRequestTemperatureContentType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static FloatRequestTemperatureContentType TextPlain { get; } = new FloatRequestTemperatureContentType(TextPlainValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(FloatRequestTemperatureContentType left, FloatRequestTemperatureContentType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(FloatRequestTemperatureContentType left, FloatRequestTemperatureContentType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator FloatRequestTemperatureContentType(string value) => new FloatRequestTemperatureContentType(value); + + /// The object to compare. + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is FloatRequestTemperatureContentType other && Equals(other); + + /// The instance to compare. + public bool Equals(FloatRequestTemperatureContentType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.Serialization.cs new file mode 100644 index 00000000000..478351990bb --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.Serialization.cs @@ -0,0 +1,21 @@ +#nullable disable + +using System.ClientModel.Primitives; + +namespace Payload.MultiPart.Models +{ + public partial class JsonPartRequest + { + + internal virtual MultiPartFormDataBinaryContent ToMultipartBinaryBody() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + content.Add(ModelReaderWriter.Write(Address, ModelSerializationExtensions.WireOptions), "address"); + // TO-DO: How do we know which model is a file? + // Possible solution: When creating the file model in the emitter, the emitter can add a new nullable property + // 'isFile' to the model. If the property is not null or true, then the model is a file. + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.cs new file mode 100644 index 00000000000..1373c886798 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/JsonPartRequest.cs @@ -0,0 +1,28 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.IO; + +namespace Payload.MultiPart.Models +{ + /// The JsonPartRequest. + public partial class JsonPartRequest + { + public JsonPartRequest(Address address, ProfileImageFileDetails profileImage) + { + Argument.AssertNotNull(address, nameof(address)); + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + Address = address; + ProfileImage = profileImage; + } + + /// Gets the address. + public Address Address { get; } + /// Gets the profile image. + public ProfileImageFileDetails ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.Serialization.cs new file mode 100644 index 00000000000..79739adf21e --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.Serialization.cs @@ -0,0 +1,29 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using Microsoft.CodeAnalysis; + +namespace Payload.MultiPart.Models +{ + public partial class MultiBinaryPartsRequest + { + internal MultiPartFormDataBinaryContent ToMultipartBinaryBody() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + + if (Optional.IsDefined(Picture)) + { + content.Add(Picture.Contents, "picture", Picture.Filename, Picture.ContentType); + } + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.cs new file mode 100644 index 00000000000..0f3bab0099a --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiBinaryPartsRequest.cs @@ -0,0 +1,26 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.IO; + +namespace Payload.MultiPart.Models +{ + /// The MultiBinaryPartsRequest. + public partial class MultiBinaryPartsRequest + { + public MultiBinaryPartsRequest(ProfileImageFileDetails profileImage) + { + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + ProfileImage = profileImage; + } + + /// Gets the profile image. + public ProfileImageFileDetails ProfileImage { get; } + /// Gets or sets the picture. + public PictureFileDetails Picture { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.Serialization.cs new file mode 100644 index 00000000000..f1c7d35ff86 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.Serialization.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; + +namespace Payload.MultiPart.Models +{ + public partial class MultiPartRequest + { + + internal MultiPartFormDataBinaryContent ToMultipartContent() + { + MultiPartFormDataBinaryContent content = new MultiPartFormDataBinaryContent(); + + content.Add(ProfileImage.Contents, "profileImage", ProfileImage.Filename, ProfileImage.ContentType); + content.Add(Id, "id"); + + return content; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.cs new file mode 100644 index 00000000000..2c15a8d0a45 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/MultiPartRequest.cs @@ -0,0 +1,24 @@ +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Payload.MultiPart.Models +{ + public partial class MultiPartRequest + { + public MultiPartRequest(string id, ProfileImageFileDetails profileImage) + { + Argument.AssertNotNull(id, nameof(id)); + Argument.AssertNotNull(profileImage, nameof(profileImage)); + + Id = id; + ProfileImage = profileImage; + } + + // Do we need a serialization constructor? + + public string Id { get; } + public ProfileImageFileDetails ProfileImage { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PictureFileDetails.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PictureFileDetails.cs new file mode 100644 index 00000000000..5305cec7d63 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PictureFileDetails.cs @@ -0,0 +1,21 @@ +#nullable disable + +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class PictureFileDetails + { + public PictureFileDetails(Stream contents) + { + Argument.AssertNotNull(contents, nameof(contents)); + + Contents = contents; + } + + public Stream Contents { get; } + + public string Filename { get; set; } + public string ContentType { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PicturesFileDetails.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PicturesFileDetails.cs new file mode 100644 index 00000000000..b50d3c0b5ac --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/PicturesFileDetails.cs @@ -0,0 +1,21 @@ + +#nullable disable + +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class PicturesFileDetails + { + public PicturesFileDetails(Stream contents) + { + Argument.AssertNotNull(contents, nameof(contents)); + + Contents = contents; + } + + public Stream Contents { get; } + public string Filename { get; set; } + public string ContentType { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ProfileImageFileDetails.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ProfileImageFileDetails.cs new file mode 100644 index 00000000000..309611cb7b4 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/Models/ProfileImageFileDetails.cs @@ -0,0 +1,20 @@ +#nullable disable + +using System.IO; + +namespace Payload.MultiPart.Models +{ + public partial class ProfileImageFileDetails + { + public ProfileImageFileDetails(Stream contents) + { + Argument.AssertNotNull(contents, nameof(contents)); + + Contents = contents; + } + + public Stream Contents { get; } + public string Filename { get; set; } + public string ContentType { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.RestClient.cs new file mode 100644 index 00000000000..8af8bf480bc --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.RestClient.cs @@ -0,0 +1,11 @@ +// + +#nullable disable + +namespace Payload.MultiPart +{ + /// + public partial class MultiPartClient + { + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.cs index 8628a0b7f5c..d76df4d38a1 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClient.cs @@ -4,17 +4,42 @@ using System; using System.ClientModel.Primitives; +using System.Threading; namespace Payload.MultiPart { + /// public partial class MultiPartClient { - public MultiPartClient() : this(new Uri("http://localhost:3000"), new MultiPartClientOptions()) => throw null; + private readonly Uri _endpoint; + private FormData _cachedFormData; - public MultiPartClient(Uri endpoint, MultiPartClientOptions options) => throw null; + /// Initializes a new instance of MultiPartClient. + public MultiPartClient() : this(new Uri("http://localhost:3000"), new MultiPartClientOptions()) + { + } - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of MultiPartClient. + /// Service endpoint. + /// The options for configuring the client. + /// is null. + public MultiPartClient(Uri endpoint, MultiPartClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); - public virtual FormData GetFormDataClient() => throw null; + options ??= new MultiPartClientOptions(); + + _endpoint = endpoint; + Pipeline = ClientPipeline.Create(options, Array.Empty(), Array.Empty(), Array.Empty()); + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// Initializes a new instance of FormData. + public virtual FormData GetFormDataClient() + { + return Volatile.Read(ref _cachedFormData) ?? Interlocked.CompareExchange(ref _cachedFormData, new FormData(Pipeline, _endpoint), null) ?? _cachedFormData; + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClientOptions.cs b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClientOptions.cs index 637c71f86aa..89d66d75f2c 100644 --- a/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClientOptions.cs +++ b/packages/http-client-csharp/generator/TestProjects/CadlRanch/http/payload/multipart/src/Generated/MultiPartClientOptions.cs @@ -6,6 +6,7 @@ namespace Payload.MultiPart { + /// Client options for . public partial class MultiPartClientOptions : ClientPipelineOptions { }