From 8513f93539b4b65d3164dd2c0b7271732da3279c Mon Sep 17 00:00:00 2001 From: mcgallan <88413158+mcgallan@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:22:51 +0800 Subject: [PATCH] Add Client Example Test And Fix ResourceManager Resource Test (#5153) * generate * regen * update * Update resource-manager-resources.cs * update --- eng/testProjects.json | 1 + .../Properties/launchSettings.json | 4 + .../azure-example-client-basic.cs | 38 + .../resource-manager-resources.cs | 55 +- .../azure/example/basic/Configuration.json | 12 + .../basic/_Specs_.Azure.Example.Basic.sln | 50 ++ .../basic/src/Generated/AzureExampleClient.cs | 208 +++++ .../Generated/AzureExampleClientOptions.cs | 37 + .../src/Generated/Docs/AzureExampleClient.xml | 111 +++ .../basic/src/Generated/Internal/Argument.cs | 129 ++++ .../Internal/ChangeTrackingDictionary.cs | 167 ++++ .../Generated/Internal/ChangeTrackingList.cs | 153 ++++ .../Internal/ModelSerializationExtensions.cs | 398 ++++++++++ .../basic/src/Generated/Internal/Optional.cs | 51 ++ .../Internal/Utf8JsonRequestContent.cs | 55 ++ .../Models/ActionRequest.Serialization.cs | 202 +++++ .../src/Generated/Models/ActionRequest.cs | 89 +++ .../Models/ActionResponse.Serialization.cs | 202 +++++ .../src/Generated/Models/ActionResponse.cs | 89 +++ .../basic/src/Generated/Models/Enum.cs | 48 ++ .../Generated/Models/Model.Serialization.cs | 173 +++++ .../basic/src/Generated/Models/Model.cs | 73 ++ ...zureExampleBasicClientBuilderExtensions.cs | 35 + .../SpecsAzureExampleBasicModelFactory.cs | 44 ++ .../basic/src/Properties/AssemblyInfo.cs | 6 + .../src/_Specs_.Azure.Example.Basic.csproj | 19 + .../Samples/Samples_AzureExampleClient.cs | 127 +++ .../_Specs_.Azure.Example.Basic.Tests.csproj | 19 + .../azure/example/basic/tspCodeModel.json | 731 ++++++++++++++++++ .../azure/example/basic/tspconfig.yaml | 4 + 30 files changed, 3308 insertions(+), 22 deletions(-) create mode 100644 test/CadlRanchProjects.Tests/azure-example-client-basic.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/Configuration.json create mode 100644 test/CadlRanchProjects/azure/example/basic/_Specs_.Azure.Example.Basic.sln create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClient.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClientOptions.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Docs/AzureExampleClient.xml create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Argument.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingDictionary.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingList.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ModelSerializationExtensions.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Optional.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Utf8JsonRequestContent.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.Serialization.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.Serialization.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Enum.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.Serialization.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicClientBuilderExtensions.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicModelFactory.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/Properties/AssemblyInfo.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/src/_Specs_.Azure.Example.Basic.csproj create mode 100644 test/CadlRanchProjects/azure/example/basic/tests/Generated/Samples/Samples_AzureExampleClient.cs create mode 100644 test/CadlRanchProjects/azure/example/basic/tests/_Specs_.Azure.Example.Basic.Tests.csproj create mode 100644 test/CadlRanchProjects/azure/example/basic/tspCodeModel.json create mode 100644 test/CadlRanchProjects/azure/example/basic/tspconfig.yaml diff --git a/eng/testProjects.json b/eng/testProjects.json index 5211fcc1b5c..1af0e56bcb9 100644 --- a/eng/testProjects.json +++ b/eng/testProjects.json @@ -32,6 +32,7 @@ "azure/client-generator-core/access", "azure/client-generator-core/flatten-property", "azure/client-generator-core/usage", + "azure/example/basic", "azure/resource-manager/common-properties", "azure/special-headers/client-request-id", "encode/bytes", diff --git a/src/AutoRest.CSharp/Properties/launchSettings.json b/src/AutoRest.CSharp/Properties/launchSettings.json index 3d483bbe1fc..e4686c415e6 100644 --- a/src/AutoRest.CSharp/Properties/launchSettings.json +++ b/src/AutoRest.CSharp/Properties/launchSettings.json @@ -652,6 +652,10 @@ "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\core\\traits\\src\\Generated -n" }, + "typespec-azure/example/basic": { + "commandName": "Project", + "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\example\\basic\\src\\Generated -n" + }, "typespec-azure/resource-manager/common-properties": { "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\resource-manager\\common-properties\\src\\Generated -n" diff --git a/test/CadlRanchProjects.Tests/azure-example-client-basic.cs b/test/CadlRanchProjects.Tests/azure-example-client-basic.cs new file mode 100644 index 00000000000..f872bc7f22f --- /dev/null +++ b/test/CadlRanchProjects.Tests/azure-example-client-basic.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using _Specs_.Azure.Core.Page; +using _Specs_.Azure.Example.Basic; +using _Specs_.Azure.Example.Basic.Models; +using AutoRest.TestServer.Tests.Infrastructure; +using NUnit.Framework; + +namespace CadlRanchProjects.Tests +{ + public class azure_example_client_basic : CadlRanchTestBase + { + [Test] + public Task Azure_Example_Client_BasicAction() => Test(async (host) => + { + var request = new ActionRequest("text") + { + ModelProperty = new Model() + { + EnumProperty = _Specs_.Azure.Example.Basic.Models.Enum.EnumValue1, + Int32Property = 1, + Float32Property = 1.5f, + }, + ArrayProperty = + { + "item" + }, + RecordProperty = + { + { "record", "value" } + } + }; + var response = await new AzureExampleClient(host, null).BasicActionAsync("query", "header", request); + Assert.AreEqual(200, response.GetRawResponse().Status); + Assert.AreEqual("text", response.Value.StringProperty); + }); + } +} diff --git a/test/CadlRanchProjects.Tests/resource-manager-resources.cs b/test/CadlRanchProjects.Tests/resource-manager-resources.cs index 68d37582708..d8b55fb1e97 100644 --- a/test/CadlRanchProjects.Tests/resource-manager-resources.cs +++ b/test/CadlRanchProjects.Tests/resource-manager-resources.cs @@ -102,18 +102,24 @@ public Task Azure_ResourceManager_Resources_TopLevelTrackedResources_delete() => public Task Azure_ResourceManager_Resources_TopLevelTrackedResources_listByResourceGroup() => Test(async (host) => { var id = ResourceGroupResource.CreateResourceIdentifier(Guid.Empty.ToString(), "test-rg"); - var response = await MgmtTestHelper.CreateArmClientWithMockAuth(host).GetResourceGroupResource(id).GetTopLevelTrackedResourceAsync("top"); - Assert.AreEqual(200, response.GetRawResponse().Status); - Assert.AreEqual(true, response.Value.HasData); - Assert.AreEqual("top", response.Value.Data.Name); - Assert.AreEqual("Azure.ResourceManager.Resources/topLevelTrackedResources", response.Value.Data.ResourceType.ToString()); - Assert.AreEqual(AzureLocation.EastUS, response.Value.Data.Location); - Assert.AreEqual("valid", response.Value.Data.Properties.Description); - Assert.AreEqual(ProvisioningState.Succeeded, response.Value.Data.Properties.ProvisioningState); - Assert.AreEqual("AzureSDK", response.Value.Data.SystemData.CreatedBy); - Assert.AreEqual(CreatedByType.User, response.Value.Data.SystemData.CreatedByType); - Assert.AreEqual("AzureSDK", response.Value.Data.SystemData.LastModifiedBy); - Assert.AreEqual(CreatedByType.User, response.Value.Data.SystemData.LastModifiedByType); + var resourceGroup = MgmtTestHelper.CreateArmClientWithMockAuth(host).GetResourceGroupResource(id); + var collection = resourceGroup.GetTopLevelTrackedResources(); + int count = 0; + await foreach (var resource in collection.GetAllAsync()) + { + count++; + Assert.AreEqual(true, resource.HasData); + Assert.AreEqual("top", resource.Data.Name); + Assert.AreEqual("Azure.ResourceManager.Resources/topLevelTrackedResources", resource.Data.ResourceType.ToString()); + Assert.AreEqual(AzureLocation.EastUS, resource.Data.Location); + Assert.AreEqual("valid", resource.Data.Properties.Description); + Assert.AreEqual(ProvisioningState.Succeeded, resource.Data.Properties.ProvisioningState); + Assert.AreEqual("AzureSDK", resource.Data.SystemData.CreatedBy); + Assert.AreEqual(CreatedByType.User, resource.Data.SystemData.CreatedByType); + Assert.AreEqual("AzureSDK", resource.Data.SystemData.LastModifiedBy); + Assert.AreEqual(CreatedByType.User, resource.Data.SystemData.LastModifiedByType); + } + Assert.AreEqual(1, count); }); [Test] @@ -213,16 +219,21 @@ public Task Azure_ResourceManager_Resources_NestedProxyResources_delete() => Tes public Task Azure_ResourceManager_Resources_NestedProxyResources_listByTopLevelTrackedResource() => Test(async (host) => { var id = TopLevelTrackedResource.CreateResourceIdentifier(Guid.Empty.ToString(), "test-rg", "top"); - var response = await MgmtTestHelper.CreateArmClientWithMockAuth(host).GetTopLevelTrackedResource(id).GetNestedProxyResourceAsync("nested"); - Assert.AreEqual(200, response.GetRawResponse().Status); - Assert.AreEqual(true, response.Value.HasData); - Assert.AreEqual("Azure.ResourceManager.Resources/topLevelTrackedResources/top/nestedProxyResources", response.Value.Data.ResourceType.ToString()); - Assert.AreEqual("valid", response.Value.Data.Properties.Description); - Assert.AreEqual(ProvisioningState.Succeeded, response.Value.Data.Properties.ProvisioningState); - Assert.AreEqual("AzureSDK", response.Value.Data.SystemData.CreatedBy); - Assert.AreEqual(CreatedByType.User, response.Value.Data.SystemData.CreatedByType); - Assert.AreEqual("AzureSDK", response.Value.Data.SystemData.LastModifiedBy); - Assert.AreEqual(CreatedByType.User, response.Value.Data.SystemData.LastModifiedByType); + var collection = MgmtTestHelper.CreateArmClientWithMockAuth(host).GetTopLevelTrackedResource(id).GetNestedProxyResources(); + int count = 0; + await foreach (var resource in collection.GetAllAsync()) + { + count++; + Assert.AreEqual(true, resource.HasData); + Assert.AreEqual("Azure.ResourceManager.Resources/topLevelTrackedResources/top/nestedProxyResources", resource.Data.ResourceType.ToString()); + Assert.AreEqual("valid", resource.Data.Properties.Description); + Assert.AreEqual(ProvisioningState.Succeeded, resource.Data.Properties.ProvisioningState); + Assert.AreEqual("AzureSDK", resource.Data.SystemData.CreatedBy); + Assert.AreEqual(CreatedByType.User, resource.Data.SystemData.CreatedByType); + Assert.AreEqual("AzureSDK", resource.Data.SystemData.LastModifiedBy); + Assert.AreEqual(CreatedByType.User, resource.Data.SystemData.LastModifiedByType); + } + Assert.AreEqual(1, count); }); [Test] diff --git a/test/CadlRanchProjects/azure/example/basic/Configuration.json b/test/CadlRanchProjects/azure/example/basic/Configuration.json new file mode 100644 index 00000000000..21f5769da04 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/Configuration.json @@ -0,0 +1,12 @@ +{ + "output-folder": ".", + "namespace": "_Specs_.Azure.Example.Basic", + "library-name": "_Specs_.Azure.Example.Basic", + "flavor": "azure", + "use-model-reader-writer": true, + "shared-source-folders": [ + "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net8.0/Generator.Shared", + "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net8.0/Azure.Core.Shared" + ], + "examples-dir": "..\\..\\..\\..\\..\\node_modules\\@azure-tools\\cadl-ranch-specs\\http\\azure\\example\\basic\\examples" +} diff --git a/test/CadlRanchProjects/azure/example/basic/_Specs_.Azure.Example.Basic.sln b/test/CadlRanchProjects/azure/example/basic/_Specs_.Azure.Example.Basic.sln new file mode 100644 index 00000000000..162c8af0f75 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/_Specs_.Azure.Example.Basic.sln @@ -0,0 +1,50 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_Specs_.Azure.Example.Basic", "src\_Specs_.Azure.Example.Basic.csproj", "{28FF4005-4467-4E36-92E7-DEA27DEB1519}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_Specs_.Azure.Example.Basic.Tests", "tests\_Specs_.Azure.Example.Basic.Tests.csproj", "{1F1CD1D4-9932-4B73-99D8-C252A67D4B46}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.Build.0 = Release|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.Build.0 = Release|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.Build.0 = Release|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.Build.0 = Release|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.Build.0 = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.Build.0 = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A97F4B90-2591-4689-B1F8-5F21FE6D6CAE} + EndGlobalSection +EndGlobal diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClient.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClient.cs new file mode 100644 index 00000000000..c7660ef8d0c --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClient.cs @@ -0,0 +1,208 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; +using _Specs_.Azure.Example.Basic.Models; + +namespace _Specs_.Azure.Example.Basic +{ + // Data plane generated client. + /// The AzureExample service client. + public partial class AzureExampleClient + { + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public virtual HttpPipeline Pipeline => _pipeline; + + /// Initializes a new instance of AzureExampleClient. + public AzureExampleClient() : this(new Uri("http://localhost:3000"), new AzureExampleClientOptions()) + { + } + + /// Initializes a new instance of AzureExampleClient. + /// Service host. + /// The options for configuring the client. + /// is null. + public AzureExampleClient(Uri endpoint, AzureExampleClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); + options ??= new AzureExampleClientOptions(); + + ClientDiagnostics = new ClientDiagnostics(options, true); + _pipeline = HttpPipelineBuilder.Build(options, Array.Empty(), Array.Empty(), new ResponseClassifier()); + _endpoint = endpoint; + _apiVersion = options.Version; + } + + /// Basic action. + /// The to use. + /// The to use. + /// The to use. + /// The cancellation token to use. + /// , or is null. + /// + public virtual async Task> BasicActionAsync(string queryParam, string headerParam, ActionRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(queryParam, nameof(queryParam)); + Argument.AssertNotNull(headerParam, nameof(headerParam)); + Argument.AssertNotNull(body, nameof(body)); + + using RequestContent content = body.ToRequestContent(); + RequestContext context = FromCancellationToken(cancellationToken); + Response response = await BasicActionAsync(queryParam, headerParam, content, context).ConfigureAwait(false); + return Response.FromValue(ActionResponse.FromResponse(response), response); + } + + /// Basic action. + /// The to use. + /// The to use. + /// The to use. + /// The cancellation token to use. + /// , or is null. + /// + public virtual Response BasicAction(string queryParam, string headerParam, ActionRequest body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(queryParam, nameof(queryParam)); + Argument.AssertNotNull(headerParam, nameof(headerParam)); + Argument.AssertNotNull(body, nameof(body)); + + using RequestContent content = body.ToRequestContent(); + RequestContext context = FromCancellationToken(cancellationToken); + Response response = BasicAction(queryParam, headerParam, content, context); + return Response.FromValue(ActionResponse.FromResponse(response), response); + } + + /// + /// [Protocol Method] Basic action. + /// + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// + /// Please try the simpler convenience overload with strongly typed models first. + /// + /// + /// + /// + /// The to use. + /// The to use. + /// The content to send as the body of the request. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// , or is null. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual async Task BasicActionAsync(string queryParam, string headerParam, RequestContent content, RequestContext context = null) + { + Argument.AssertNotNull(queryParam, nameof(queryParam)); + Argument.AssertNotNull(headerParam, nameof(headerParam)); + Argument.AssertNotNull(content, nameof(content)); + + using var scope = ClientDiagnostics.CreateScope("AzureExampleClient.BasicAction"); + scope.Start(); + try + { + using HttpMessage message = CreateBasicActionRequest(queryParam, headerParam, content, context); + return await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// + /// [Protocol Method] Basic action. + /// + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// + /// Please try the simpler convenience overload with strongly typed models first. + /// + /// + /// + /// + /// The to use. + /// The to use. + /// The content to send as the body of the request. + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// , or is null. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual Response BasicAction(string queryParam, string headerParam, RequestContent content, RequestContext context = null) + { + Argument.AssertNotNull(queryParam, nameof(queryParam)); + Argument.AssertNotNull(headerParam, nameof(headerParam)); + Argument.AssertNotNull(content, nameof(content)); + + using var scope = ClientDiagnostics.CreateScope("AzureExampleClient.BasicAction"); + scope.Start(); + try + { + using HttpMessage message = CreateBasicActionRequest(queryParam, headerParam, content, context); + return _pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + internal HttpMessage CreateBasicActionRequest(string queryParam, string headerParam, RequestContent content, RequestContext context) + { + var message = _pipeline.CreateMessage(context, ResponseClassifier200); + var request = message.Request; + request.Method = RequestMethod.Post; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/azure/example/basic/basic", false); + uri.AppendQuery("query-param", queryParam, true); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("header-param", headerParam); + request.Headers.Add("Accept", "application/json"); + request.Headers.Add("Content-Type", "application/json"); + request.Content = content; + return message; + } + + private static RequestContext DefaultRequestContext = new RequestContext(); + internal static RequestContext FromCancellationToken(CancellationToken cancellationToken = default) + { + if (!cancellationToken.CanBeCanceled) + { + return DefaultRequestContext; + } + + return new RequestContext() { CancellationToken = cancellationToken }; + } + + private static ResponseClassifier _responseClassifier200; + private static ResponseClassifier ResponseClassifier200 => _responseClassifier200 ??= new StatusCodeClassifier(stackalloc ushort[] { 200 }); + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClientOptions.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClientOptions.cs new file mode 100644 index 00000000000..457942e8443 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/AzureExampleClientOptions.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic +{ + /// Client options for AzureExampleClient. + public partial class AzureExampleClientOptions : ClientOptions + { + private const ServiceVersion LatestVersion = ServiceVersion.V2022_12_01_Preview; + + /// The version of the service to use. + public enum ServiceVersion + { + /// Service version "2022-12-01-preview". + V2022_12_01_Preview = 1, + } + + internal string Version { get; } + + /// Initializes new instance of AzureExampleClientOptions. + public AzureExampleClientOptions(ServiceVersion version = LatestVersion) + { + Version = version switch + { + ServiceVersion.V2022_12_01_Preview => "2022-12-01-preview", + _ => throw new NotSupportedException() + }; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Docs/AzureExampleClient.xml b/test/CadlRanchProjects/azure/example/basic/src/Generated/Docs/AzureExampleClient.xml new file mode 100644 index 00000000000..da751c75dee --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Docs/AzureExampleClient.xml @@ -0,0 +1,111 @@ + + + + + +This sample shows how to call BasicActionAsync. + response = await client.BasicActionAsync("query", "header", body); +]]> + + + +This sample shows how to call BasicAction. + response = client.BasicAction("query", "header", body); +]]> + + + +This sample shows how to call BasicActionAsync and parse the result. + + + + +This sample shows how to call BasicAction and parse the result. + + + + \ No newline at end of file diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Argument.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Argument.cs new file mode 100644 index 00000000000..01a4c8fce3e --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Argument.cs @@ -0,0 +1,129 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace _Specs_.Azure.Example.Basic +{ + internal static 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/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingDictionary.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingDictionary.cs new file mode 100644 index 00000000000..f66f9cd0389 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingDictionary.cs @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace _Specs_.Azure.Example.Basic +{ + internal class ChangeTrackingDictionary : IDictionary, IReadOnlyDictionary where TKey : notnull + { + private IDictionary _innerDictionary; + + public ChangeTrackingDictionary() + { + } + + public ChangeTrackingDictionary(IDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(dictionary); + } + + public ChangeTrackingDictionary(IReadOnlyDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(); + foreach (var pair in dictionary) + { + _innerDictionary.Add(pair); + } + } + + public bool IsUndefined => _innerDictionary == null; + + public int Count => IsUndefined ? 0 : EnsureDictionary().Count; + + public bool IsReadOnly => IsUndefined ? false : EnsureDictionary().IsReadOnly; + + public ICollection Keys => IsUndefined ? Array.Empty() : EnsureDictionary().Keys; + + public ICollection Values => IsUndefined ? Array.Empty() : EnsureDictionary().Values; + + public TValue this[TKey key] + { + get + { + if (IsUndefined) + { + throw new KeyNotFoundException(nameof(key)); + } + return EnsureDictionary()[key]; + } + set + { + EnsureDictionary()[key] = value; + } + } + + IEnumerable IReadOnlyDictionary.Keys => Keys; + + IEnumerable IReadOnlyDictionary.Values => Values; + + public IEnumerator> GetEnumerator() + { + if (IsUndefined) + { + IEnumerator> enumerateEmpty() + { + yield break; + } + return enumerateEmpty(); + } + return EnsureDictionary().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(KeyValuePair item) + { + EnsureDictionary().Add(item); + } + + public void Clear() + { + EnsureDictionary().Clear(); + } + + public bool Contains(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int index) + { + if (IsUndefined) + { + return; + } + EnsureDictionary().CopyTo(array, index); + } + + public bool Remove(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(item); + } + + public void Add(TKey key, TValue value) + { + EnsureDictionary().Add(key, value); + } + + public bool ContainsKey(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().ContainsKey(key); + } + + public bool Remove(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(key); + } + + public bool TryGetValue(TKey key, out TValue value) + { + if (IsUndefined) + { + value = default; + return false; + } + return EnsureDictionary().TryGetValue(key, out value); + } + + public IDictionary EnsureDictionary() + { + return _innerDictionary ??= new Dictionary(); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingList.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingList.cs new file mode 100644 index 00000000000..7f0a3bc417f --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ChangeTrackingList.cs @@ -0,0 +1,153 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace _Specs_.Azure.Example.Basic +{ + internal class ChangeTrackingList : IList, IReadOnlyList + { + private IList _innerList; + + public ChangeTrackingList() + { + } + + public ChangeTrackingList(IList innerList) + { + if (innerList != null) + { + _innerList = innerList; + } + } + + public ChangeTrackingList(IReadOnlyList innerList) + { + if (innerList != null) + { + _innerList = innerList.ToList(); + } + } + + public bool IsUndefined => _innerList == null; + + public int Count => IsUndefined ? 0 : EnsureList().Count; + + public bool IsReadOnly => IsUndefined ? false : EnsureList().IsReadOnly; + + public T this[int index] + { + get + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + return EnsureList()[index]; + } + set + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + EnsureList()[index] = value; + } + } + + public void Reset() + { + _innerList = null; + } + + public IEnumerator GetEnumerator() + { + if (IsUndefined) + { + IEnumerator enumerateEmpty() + { + yield break; + } + return enumerateEmpty(); + } + return EnsureList().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(T item) + { + EnsureList().Add(item); + } + + public void Clear() + { + EnsureList().Clear(); + } + + public bool Contains(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + if (IsUndefined) + { + return; + } + EnsureList().CopyTo(array, arrayIndex); + } + + public bool Remove(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Remove(item); + } + + public int IndexOf(T item) + { + if (IsUndefined) + { + return -1; + } + return EnsureList().IndexOf(item); + } + + public void Insert(int index, T item) + { + EnsureList().Insert(index, item); + } + + public void RemoveAt(int index) + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + EnsureList().RemoveAt(index); + } + + public IList EnsureList() + { + return _innerList ??= new List(); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ModelSerializationExtensions.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ModelSerializationExtensions.cs new file mode 100644 index 00000000000..2dcf0fa2691 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/ModelSerializationExtensions.cs @@ -0,0 +1,398 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Text.Json; +using System.Xml; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic +{ + internal static 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: + var dictionary = new Dictionary(); + foreach (var jsonProperty in element.EnumerateObject()) + { + dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); + } + return dictionary; + case JsonValueKind.Array: + var 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) + { + var 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) + { + var 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 IUtf8JsonSerializable serializable: + serializable.Write(writer); + 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); + } + + internal static 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}. Azure SDK requires 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" => 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" => 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 => XmlConvert.ToString(timeSpan0), + Guid guid => guid.ToString(), + BinaryData binaryData => ConvertToString(binaryData.ToArray(), format), + _ => value.ToString() + }; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Optional.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Optional.cs new file mode 100644 index 00000000000..a0f683425d9 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Optional.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Text.Json; + +namespace _Specs_.Azure.Example.Basic +{ + internal static 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(JsonElement value) + { + return value.ValueKind != JsonValueKind.Undefined; + } + + public static bool IsDefined(string value) + { + return value != null; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Utf8JsonRequestContent.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Utf8JsonRequestContent.cs new file mode 100644 index 00000000000..fbaa86af86a --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Internal/Utf8JsonRequestContent.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.IO; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic +{ + internal class Utf8JsonRequestContent : RequestContent + { + private readonly MemoryStream _stream; + private readonly RequestContent _content; + + public Utf8JsonRequestContent() + { + _stream = new MemoryStream(); + _content = Create(_stream); + JsonWriter = new Utf8JsonWriter(_stream); + } + + public Utf8JsonWriter JsonWriter { get; } + + public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken = default) + { + await JsonWriter.FlushAsync().ConfigureAwait(false); + await _content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); + } + + public override void WriteTo(Stream stream, CancellationToken cancellationToken = default) + { + JsonWriter.Flush(); + _content.WriteTo(stream, cancellationToken); + } + + public override bool TryComputeLength(out long length) + { + length = JsonWriter.BytesCommitted + JsonWriter.BytesPending; + return true; + } + + public override void Dispose() + { + JsonWriter.Dispose(); + _content.Dispose(); + _stream.Dispose(); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.Serialization.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.Serialization.cs new file mode 100644 index 00000000000..1cd95fbc823 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.Serialization.cs @@ -0,0 +1,202 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic.Models +{ + public partial class ActionRequest : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ActionRequest)} does not support writing '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("stringProperty"u8); + writer.WriteStringValue(StringProperty); + if (Optional.IsDefined(ModelProperty)) + { + writer.WritePropertyName("modelProperty"u8); + writer.WriteObjectValue(ModelProperty, options); + } + if (Optional.IsCollectionDefined(ArrayProperty)) + { + writer.WritePropertyName("arrayProperty"u8); + writer.WriteStartArray(); + foreach (var item in ArrayProperty) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(RecordProperty)) + { + writer.WritePropertyName("recordProperty"u8); + writer.WriteStartObject(); + foreach (var item in RecordProperty) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + 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 + } + } + writer.WriteEndObject(); + } + + ActionRequest IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ActionRequest)} does not support reading '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeActionRequest(document.RootElement, options); + } + + internal static ActionRequest DeserializeActionRequest(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= ModelSerializationExtensions.WireOptions; + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string stringProperty = default; + Model modelProperty = default; + IList arrayProperty = default; + IDictionary recordProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary rawDataDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("stringProperty"u8)) + { + stringProperty = property.Value.GetString(); + continue; + } + if (property.NameEquals("modelProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + modelProperty = Model.DeserializeModel(property.Value, options); + continue; + } + if (property.NameEquals("arrayProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + arrayProperty = array; + continue; + } + if (property.NameEquals("recordProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + Dictionary dictionary = new Dictionary(); + foreach (var property0 in property.Value.EnumerateObject()) + { + dictionary.Add(property0.Name, property0.Value.GetString()); + } + recordProperty = dictionary; + continue; + } + if (options.Format != "W") + { + rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = rawDataDictionary; + return new ActionRequest(stringProperty, modelProperty, arrayProperty ?? new ChangeTrackingList(), recordProperty ?? new ChangeTrackingDictionary(), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(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(ActionRequest)} does not support writing '{options.Format}' format."); + } + } + + ActionRequest IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeActionRequest(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ActionRequest)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static ActionRequest FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeActionRequest(document.RootElement); + } + + /// Convert into a . + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this, ModelSerializationExtensions.WireOptions); + return content; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.cs new file mode 100644 index 00000000000..2f750f32ced --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionRequest.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace _Specs_.Azure.Example.Basic.Models +{ + /// The ActionRequest. + public partial class ActionRequest + { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + + /// Initializes a new instance of . + /// + /// is null. + public ActionRequest(string stringProperty) + { + Argument.AssertNotNull(stringProperty, nameof(stringProperty)); + + StringProperty = stringProperty; + ArrayProperty = new ChangeTrackingList(); + RecordProperty = new ChangeTrackingDictionary(); + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal ActionRequest(string stringProperty, Model modelProperty, IList arrayProperty, IDictionary recordProperty, IDictionary serializedAdditionalRawData) + { + StringProperty = stringProperty; + ModelProperty = modelProperty; + ArrayProperty = arrayProperty; + RecordProperty = recordProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ActionRequest() + { + } + + /// Gets the string property. + public string StringProperty { get; } + /// Gets or sets the model property. + public Model ModelProperty { get; set; } + /// Gets the array property. + public IList ArrayProperty { get; } + /// Gets the record property. + public IDictionary RecordProperty { get; } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.Serialization.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.Serialization.cs new file mode 100644 index 00000000000..675187715ed --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.Serialization.cs @@ -0,0 +1,202 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic.Models +{ + public partial class ActionResponse : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ActionResponse)} does not support writing '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("stringProperty"u8); + writer.WriteStringValue(StringProperty); + if (Optional.IsDefined(ModelProperty)) + { + writer.WritePropertyName("modelProperty"u8); + writer.WriteObjectValue(ModelProperty, options); + } + if (Optional.IsCollectionDefined(ArrayProperty)) + { + writer.WritePropertyName("arrayProperty"u8); + writer.WriteStartArray(); + foreach (var item in ArrayProperty) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(RecordProperty)) + { + writer.WritePropertyName("recordProperty"u8); + writer.WriteStartObject(); + foreach (var item in RecordProperty) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + 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 + } + } + writer.WriteEndObject(); + } + + ActionResponse IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ActionResponse)} does not support reading '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeActionResponse(document.RootElement, options); + } + + internal static ActionResponse DeserializeActionResponse(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= ModelSerializationExtensions.WireOptions; + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string stringProperty = default; + Model modelProperty = default; + IReadOnlyList arrayProperty = default; + IReadOnlyDictionary recordProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary rawDataDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("stringProperty"u8)) + { + stringProperty = property.Value.GetString(); + continue; + } + if (property.NameEquals("modelProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + modelProperty = Model.DeserializeModel(property.Value, options); + continue; + } + if (property.NameEquals("arrayProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + arrayProperty = array; + continue; + } + if (property.NameEquals("recordProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + Dictionary dictionary = new Dictionary(); + foreach (var property0 in property.Value.EnumerateObject()) + { + dictionary.Add(property0.Name, property0.Value.GetString()); + } + recordProperty = dictionary; + continue; + } + if (options.Format != "W") + { + rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = rawDataDictionary; + return new ActionResponse(stringProperty, modelProperty, arrayProperty ?? new ChangeTrackingList(), recordProperty ?? new ChangeTrackingDictionary(), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(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(ActionResponse)} does not support writing '{options.Format}' format."); + } + } + + ActionResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeActionResponse(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ActionResponse)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static ActionResponse FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeActionResponse(document.RootElement); + } + + /// Convert into a . + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this, ModelSerializationExtensions.WireOptions); + return content; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.cs new file mode 100644 index 00000000000..dd3eeec762f --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/ActionResponse.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace _Specs_.Azure.Example.Basic.Models +{ + /// The ActionResponse. + public partial class ActionResponse + { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + + /// Initializes a new instance of . + /// + /// is null. + internal ActionResponse(string stringProperty) + { + Argument.AssertNotNull(stringProperty, nameof(stringProperty)); + + StringProperty = stringProperty; + ArrayProperty = new ChangeTrackingList(); + RecordProperty = new ChangeTrackingDictionary(); + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal ActionResponse(string stringProperty, Model modelProperty, IReadOnlyList arrayProperty, IReadOnlyDictionary recordProperty, IDictionary serializedAdditionalRawData) + { + StringProperty = stringProperty; + ModelProperty = modelProperty; + ArrayProperty = arrayProperty; + RecordProperty = recordProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ActionResponse() + { + } + + /// Gets the string property. + public string StringProperty { get; } + /// Gets the model property. + public Model ModelProperty { get; } + /// Gets the array property. + public IReadOnlyList ArrayProperty { get; } + /// Gets the record property. + public IReadOnlyDictionary RecordProperty { get; } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Enum.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Enum.cs new file mode 100644 index 00000000000..8741d537d19 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Enum.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace _Specs_.Azure.Example.Basic.Models +{ + /// The Enum. + public readonly partial struct Enum : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public Enum(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string EnumValue1Value = "EnumValue1"; + + /// EnumValue1. + public static Enum EnumValue1 { get; } = new Enum(EnumValue1Value); + /// Determines if two values are the same. + public static bool operator ==(Enum left, Enum right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(Enum left, Enum right) => !left.Equals(right); + /// Converts a to a . + public static implicit operator Enum(string value) => new Enum(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is Enum other && Equals(other); + /// + public bool Equals(Enum 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/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.Serialization.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.Serialization.cs new file mode 100644 index 00000000000..eaab5e7c26a --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.Serialization.cs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace _Specs_.Azure.Example.Basic.Models +{ + public partial class Model : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Model)} does not support writing '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Int32Property)) + { + writer.WritePropertyName("int32Property"u8); + writer.WriteNumberValue(Int32Property.Value); + } + if (Optional.IsDefined(Float32Property)) + { + writer.WritePropertyName("float32Property"u8); + writer.WriteNumberValue(Float32Property.Value); + } + if (Optional.IsDefined(EnumProperty)) + { + writer.WritePropertyName("enumProperty"u8); + writer.WriteStringValue(EnumProperty.Value.ToString()); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + 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 + } + } + writer.WriteEndObject(); + } + + Model IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Model)} does not support reading '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModel(document.RootElement, options); + } + + internal static Model DeserializeModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= ModelSerializationExtensions.WireOptions; + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int? int32Property = default; + float? float32Property = default; + Enum? enumProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary rawDataDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("int32Property"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int32Property = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("float32Property"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + float32Property = property.Value.GetSingle(); + continue; + } + if (property.NameEquals("enumProperty"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + enumProperty = new Enum(property.Value.GetString()); + continue; + } + if (options.Format != "W") + { + rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = rawDataDictionary; + return new Model(int32Property, float32Property, enumProperty, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(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(Model)} does not support writing '{options.Format}' format."); + } + } + + Model IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Model)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static Model FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeModel(document.RootElement); + } + + /// Convert into a . + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this, ModelSerializationExtensions.WireOptions); + return content; + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.cs new file mode 100644 index 00000000000..75ad623a3d4 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/Models/Model.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace _Specs_.Azure.Example.Basic.Models +{ + /// The Model. + public partial class Model + { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + + /// Initializes a new instance of . + public Model() + { + } + + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal Model(int? int32Property, float? float32Property, Enum? enumProperty, IDictionary serializedAdditionalRawData) + { + Int32Property = int32Property; + Float32Property = float32Property; + EnumProperty = enumProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Gets or sets the int 32 property. + public int? Int32Property { get; set; } + /// Gets or sets the float 32 property. + public float? Float32Property { get; set; } + /// Gets or sets the enum property. + public Enum? EnumProperty { get; set; } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicClientBuilderExtensions.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicClientBuilderExtensions.cs new file mode 100644 index 00000000000..bb5dc4fd69b --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicClientBuilderExtensions.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core.Extensions; +using _Specs_.Azure.Example.Basic; + +namespace Microsoft.Extensions.Azure +{ + /// Extension methods to add to client builder. + public static partial class SpecsAzureExampleBasicClientBuilderExtensions + { + /// Registers a instance. + /// The builder to register with. + /// Service host. + public static IAzureClientBuilder AddAzureExampleClient(this TBuilder builder, Uri endpoint) + where TBuilder : IAzureClientFactoryBuilder + { + return builder.RegisterClientFactory((options) => new AzureExampleClient(endpoint, options)); + } + + /// Registers a instance. + /// The builder to register with. + /// The configuration values. + public static IAzureClientBuilder AddAzureExampleClient(this TBuilder builder, TConfiguration configuration) + where TBuilder : IAzureClientFactoryBuilderWithConfiguration + { + return builder.RegisterClientFactory(configuration); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicModelFactory.cs b/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicModelFactory.cs new file mode 100644 index 00000000000..401f4b4af62 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Generated/SpecsAzureExampleBasicModelFactory.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Linq; + +namespace _Specs_.Azure.Example.Basic.Models +{ + /// Model factory for models. + public static partial class SpecsAzureExampleBasicModelFactory + { + /// Initializes a new instance of . + /// + /// + /// + /// + /// A new instance for mocking. + public static ActionRequest ActionRequest(string stringProperty = null, Model modelProperty = null, IEnumerable arrayProperty = null, IDictionary recordProperty = null) + { + arrayProperty ??= new List(); + recordProperty ??= new Dictionary(); + + return new ActionRequest(stringProperty, modelProperty, arrayProperty?.ToList(), recordProperty, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// A new instance for mocking. + public static ActionResponse ActionResponse(string stringProperty = null, Model modelProperty = null, IEnumerable arrayProperty = null, IReadOnlyDictionary recordProperty = null) + { + arrayProperty ??= new List(); + recordProperty ??= new Dictionary(); + + return new ActionResponse(stringProperty, modelProperty, arrayProperty?.ToList(), recordProperty, serializedAdditionalRawData: null); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/src/Properties/AssemblyInfo.cs b/test/CadlRanchProjects/azure/example/basic/src/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..2dd4963e75f --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("_Specs_.Azure.Example.Basic.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] diff --git a/test/CadlRanchProjects/azure/example/basic/src/_Specs_.Azure.Example.Basic.csproj b/test/CadlRanchProjects/azure/example/basic/src/_Specs_.Azure.Example.Basic.csproj new file mode 100644 index 00000000000..147c5204edc --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/src/_Specs_.Azure.Example.Basic.csproj @@ -0,0 +1,19 @@ + + + This is the _Specs_.Azure.Example.Basic client library for developing .NET applications with rich experience. + Azure SDK Code Generation _Specs_.Azure.Example.Basic for Azure Data Plane + 1.0.0-beta.1 + _Specs_.Azure.Example.Basic + $(RequiredTargetFrameworks) + true + + + + + + + + + + + diff --git a/test/CadlRanchProjects/azure/example/basic/tests/Generated/Samples/Samples_AzureExampleClient.cs b/test/CadlRanchProjects/azure/example/basic/tests/Generated/Samples/Samples_AzureExampleClient.cs new file mode 100644 index 00000000000..3244267aebf --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/tests/Generated/Samples/Samples_AzureExampleClient.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Identity; +using NUnit.Framework; +using _Specs_.Azure.Example.Basic.Models; + +namespace _Specs_.Azure.Example.Basic.Samples +{ + public partial class Samples_AzureExampleClient + { + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_AzureExampleClient_BasicAction_BasicAction() + { + AzureExampleClient client = new AzureExampleClient(); + + using RequestContent content = RequestContent.Create(new + { + stringProperty = "text", + modelProperty = new + { + int32Property = 1, + float32Property = 1.5F, + enumProperty = "EnumValue1", + }, + arrayProperty = new object[] + { +"item" + }, + recordProperty = new + { + record = "value", + }, + }); + Response response = client.BasicAction("query", "header", content); + + JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement; + Console.WriteLine(result.GetProperty("stringProperty").ToString()); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_AzureExampleClient_BasicAction_BasicAction_Async() + { + AzureExampleClient client = new AzureExampleClient(); + + using RequestContent content = RequestContent.Create(new + { + stringProperty = "text", + modelProperty = new + { + int32Property = 1, + float32Property = 1.5F, + enumProperty = "EnumValue1", + }, + arrayProperty = new object[] + { +"item" + }, + recordProperty = new + { + record = "value", + }, + }); + Response response = await client.BasicActionAsync("query", "header", content); + + JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement; + Console.WriteLine(result.GetProperty("stringProperty").ToString()); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_AzureExampleClient_BasicAction_BasicAction_Convenience() + { + AzureExampleClient client = new AzureExampleClient(); + + ActionRequest body = new ActionRequest("text") + { + ModelProperty = new Model + { + Int32Property = 1, + Float32Property = 1.5F, + EnumProperty = Models.Enum.EnumValue1, + }, + ArrayProperty = { "item" }, + RecordProperty = +{ +["record"] = "value" +}, + }; + Response response = client.BasicAction("query", "header", body); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_AzureExampleClient_BasicAction_BasicAction_Convenience_Async() + { + AzureExampleClient client = new AzureExampleClient(); + + ActionRequest body = new ActionRequest("text") + { + ModelProperty = new Model + { + Int32Property = 1, + Float32Property = 1.5F, + EnumProperty = Models.Enum.EnumValue1, + }, + ArrayProperty = { "item" }, + RecordProperty = +{ +["record"] = "value" +}, + }; + Response response = await client.BasicActionAsync("query", "header", body); + } + } +} diff --git a/test/CadlRanchProjects/azure/example/basic/tests/_Specs_.Azure.Example.Basic.Tests.csproj b/test/CadlRanchProjects/azure/example/basic/tests/_Specs_.Azure.Example.Basic.Tests.csproj new file mode 100644 index 00000000000..cddf3c14b1a --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/tests/_Specs_.Azure.Example.Basic.Tests.csproj @@ -0,0 +1,19 @@ + + + $(RequiredTargetFrameworks) + + $(NoWarn);CS1591 + + + + + + + + + + + + + + diff --git a/test/CadlRanchProjects/azure/example/basic/tspCodeModel.json b/test/CadlRanchProjects/azure/example/basic/tspCodeModel.json new file mode 100644 index 00000000000..7b279741c39 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/tspCodeModel.json @@ -0,0 +1,731 @@ +{ + "$id": "1", + "Name": "_Specs_.Azure.Example.Basic", + "ApiVersions": [ + "2022-12-01-preview" + ], + "Enums": [ + { + "$id": "2", + "kind": "enum", + "name": "Enum", + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Enum", + "valueType": { + "$id": "3", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "values": [ + { + "$id": "4", + "kind": "enumvalue", + "name": "EnumValue1", + "value": "EnumValue1", + "valueType": { + "$id": "5", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "enumType": { + "$ref": "2" + }, + "decorators": [] + } + ], + "isFixed": false, + "isFlags": false, + "usage": "Input,Output,Json", + "decorators": [] + }, + { + "$id": "6", + "kind": "enum", + "name": "Versions", + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Versions", + "valueType": { + "$id": "7", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "values": [ + { + "$id": "8", + "kind": "enumvalue", + "name": "v2022_12_01_preview", + "value": "2022-12-01-preview", + "valueType": { + "$id": "9", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "enumType": { + "$ref": "6" + }, + "decorators": [] + } + ], + "isFixed": true, + "isFlags": false, + "usage": "ApiVersionEnum", + "decorators": [] + } + ], + "Models": [ + { + "$id": "10", + "kind": "model", + "name": "ActionRequest", + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionRequest", + "usage": "Input,Json", + "decorators": [], + "properties": [ + { + "$id": "11", + "kind": "property", + "name": "stringProperty", + "serializedName": "stringProperty", + "type": { + "$id": "12", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionRequest.stringProperty" + }, + { + "$id": "13", + "kind": "property", + "name": "modelProperty", + "serializedName": "modelProperty", + "type": { + "$id": "14", + "kind": "model", + "name": "Model", + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Model", + "usage": "Input,Output,Json", + "decorators": [], + "properties": [ + { + "$id": "15", + "kind": "property", + "name": "int32Property", + "serializedName": "int32Property", + "type": { + "$id": "16", + "kind": "int32", + "name": "int32", + "crossLanguageDefinitionId": "TypeSpec.int32", + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Model.int32Property" + }, + { + "$id": "17", + "kind": "property", + "name": "float32Property", + "serializedName": "float32Property", + "type": { + "$id": "18", + "kind": "float32", + "name": "float32", + "crossLanguageDefinitionId": "TypeSpec.float32", + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Model.float32Property" + }, + { + "$id": "19", + "kind": "property", + "name": "enumProperty", + "serializedName": "enumProperty", + "type": { + "$ref": "2" + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.Model.enumProperty" + } + ] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionRequest.modelProperty" + }, + { + "$id": "20", + "kind": "property", + "name": "arrayProperty", + "serializedName": "arrayProperty", + "type": { + "$id": "21", + "kind": "array", + "name": "Array", + "valueType": { + "$id": "22", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "crossLanguageDefinitionId": "TypeSpec.Array", + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionRequest.arrayProperty" + }, + { + "$id": "23", + "kind": "property", + "name": "recordProperty", + "serializedName": "recordProperty", + "type": { + "$id": "24", + "kind": "dict", + "keyType": { + "$id": "25", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "valueType": { + "$id": "26", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionRequest.recordProperty" + } + ] + }, + { + "$ref": "14" + }, + { + "$id": "27", + "kind": "model", + "name": "ActionResponse", + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionResponse", + "usage": "Output,Json", + "decorators": [], + "properties": [ + { + "$id": "28", + "kind": "property", + "name": "stringProperty", + "serializedName": "stringProperty", + "type": { + "$id": "29", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionResponse.stringProperty" + }, + { + "$id": "30", + "kind": "property", + "name": "modelProperty", + "serializedName": "modelProperty", + "type": { + "$ref": "14" + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionResponse.modelProperty" + }, + { + "$id": "31", + "kind": "property", + "name": "arrayProperty", + "serializedName": "arrayProperty", + "type": { + "$id": "32", + "kind": "array", + "name": "Array", + "valueType": { + "$id": "33", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "crossLanguageDefinitionId": "TypeSpec.Array", + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionResponse.arrayProperty" + }, + { + "$id": "34", + "kind": "property", + "name": "recordProperty", + "serializedName": "recordProperty", + "type": { + "$id": "35", + "kind": "dict", + "keyType": { + "$id": "36", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "valueType": { + "$id": "37", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "_Specs_.Azure.Example.Basic.ActionResponse.recordProperty" + } + ] + } + ], + "Clients": [ + { + "$id": "38", + "Name": "AzureExampleClient", + "Operations": [ + { + "$id": "39", + "Name": "basicAction", + "ResourceName": "AzureExampleClient", + "Accessibility": "public", + "Parameters": [ + { + "$id": "40", + "Name": "apiVersion", + "NameInRequest": "api-version", + "Description": "The API version to use for this operation.", + "Type": { + "$id": "41", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "Location": "Query", + "IsApiVersion": true, + "IsContentType": false, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Client", + "DefaultValue": { + "$id": "42", + "Type": { + "$id": "43", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string" + }, + "Value": "2022-12-01-preview" + }, + "Decorators": [], + "SkipUrlEncoding": false + }, + { + "$id": "44", + "Name": "queryParam", + "NameInRequest": "query-param", + "Type": { + "$id": "45", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "Location": "Query", + "IsApiVersion": false, + "IsContentType": false, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Method", + "Decorators": [], + "SkipUrlEncoding": false + }, + { + "$id": "46", + "Name": "headerParam", + "NameInRequest": "header-param", + "Type": { + "$id": "47", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "Location": "Header", + "IsApiVersion": false, + "IsContentType": false, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Method", + "Decorators": [], + "SkipUrlEncoding": false + }, + { + "$id": "48", + "Name": "contentType", + "NameInRequest": "Content-Type", + "Description": "Body parameter's content type. Known values are application/json", + "Type": { + "$id": "49", + "kind": "constant", + "valueType": { + "$id": "50", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + "Location": "Header", + "IsApiVersion": false, + "IsContentType": true, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Constant", + "Decorators": [], + "SkipUrlEncoding": false + }, + { + "$id": "51", + "Name": "accept", + "NameInRequest": "Accept", + "Type": { + "$id": "52", + "kind": "constant", + "valueType": { + "$id": "53", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + "Location": "Header", + "IsApiVersion": false, + "IsContentType": false, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Constant", + "Decorators": [], + "SkipUrlEncoding": false + }, + { + "$id": "54", + "Name": "body", + "NameInRequest": "body", + "Type": { + "$ref": "10" + }, + "Location": "Body", + "IsApiVersion": false, + "IsContentType": false, + "IsEndpoint": false, + "Explode": false, + "IsRequired": true, + "Kind": "Method", + "Decorators": [], + "SkipUrlEncoding": false + } + ], + "Responses": [ + { + "$id": "55", + "StatusCodes": [ + 200 + ], + "BodyType": { + "$ref": "27" + }, + "BodyMediaType": "Json", + "Headers": [], + "IsErrorResponse": false, + "ContentTypes": [ + "application/json" + ] + } + ], + "HttpMethod": "POST", + "RequestBodyMediaType": "Json", + "Uri": "{endpoint}", + "Path": "/azure/example/basic/basic", + "RequestMediaTypes": [ + "application/json" + ], + "BufferResponse": true, + "GenerateProtocolMethod": true, + "GenerateConvenienceMethod": true, + "CrossLanguageDefinitionId": "Client.AzureExampleClient.basicAction", + "Decorators": [], + "Examples": [ + { + "$id": "56", + "kind": "http", + "name": "Basic action", + "description": "Basic action", + "filePath": "2022-12-01-preview/basic.json", + "parameters": [ + { + "$id": "57", + "parameter": { + "$ref": "40" + }, + "value": { + "$id": "58", + "kind": "string", + "type": { + "$ref": "41" + }, + "value": "2022-12-01-preview" + } + }, + { + "$id": "59", + "parameter": { + "$ref": "44" + }, + "value": { + "$id": "60", + "kind": "string", + "type": { + "$ref": "45" + }, + "value": "query" + } + }, + { + "$id": "61", + "parameter": { + "$ref": "46" + }, + "value": { + "$id": "62", + "kind": "string", + "type": { + "$ref": "47" + }, + "value": "header" + } + }, + { + "$id": "63", + "parameter": { + "$ref": "54" + }, + "value": { + "$id": "64", + "kind": "model", + "type": { + "$ref": "10" + }, + "value": { + "$id": "65", + "stringProperty": { + "$id": "66", + "kind": "string", + "type": { + "$ref": "12" + }, + "value": "text" + }, + "modelProperty": { + "$id": "67", + "kind": "model", + "type": { + "$ref": "14" + }, + "value": { + "$id": "68", + "int32Property": { + "$id": "69", + "kind": "number", + "type": { + "$ref": "16" + }, + "value": 1 + }, + "float32Property": { + "$id": "70", + "kind": "number", + "type": { + "$ref": "18" + }, + "value": 1.5 + }, + "enumProperty": { + "$id": "71", + "kind": "string", + "type": { + "$ref": "2" + }, + "value": "EnumValue1" + } + } + }, + "arrayProperty": { + "$id": "72", + "kind": "array", + "type": { + "$ref": "21" + }, + "value": [ + { + "$id": "73", + "kind": "string", + "type": { + "$ref": "22" + }, + "value": "item" + } + ] + }, + "recordProperty": { + "$id": "74", + "kind": "dict", + "type": { + "$ref": "24" + }, + "value": { + "$id": "75", + "record": { + "$id": "76", + "kind": "string", + "type": { + "$ref": "26" + }, + "value": "value" + } + } + } + } + } + } + ], + "responses": [ + { + "$id": "77", + "response": { + "$ref": "55" + }, + "statusCode": 200 + } + ] + } + ] + } + ], + "Protocol": { + "$id": "78" + }, + "Parameters": [ + { + "$id": "79", + "Name": "endpoint", + "NameInRequest": "endpoint", + "Description": "Service host", + "Type": { + "$id": "80", + "kind": "url", + "name": "url", + "crossLanguageDefinitionId": "TypeSpec.url" + }, + "Location": "Uri", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": true, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Client", + "DefaultValue": { + "$id": "81", + "Type": { + "$id": "82", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string" + }, + "Value": "http://localhost:3000" + } + } + ], + "Decorators": [] + } + ] +} diff --git a/test/CadlRanchProjects/azure/example/basic/tspconfig.yaml b/test/CadlRanchProjects/azure/example/basic/tspconfig.yaml new file mode 100644 index 00000000000..221e9ec7ae5 --- /dev/null +++ b/test/CadlRanchProjects/azure/example/basic/tspconfig.yaml @@ -0,0 +1,4 @@ +options: + "@azure-tools/typespec-csharp": + clear-output-folder: true + examples-dir: "{project-root}/../../../../../node_modules/@azure-tools/cadl-ranch-specs/http/azure/example/basic/examples"