From 1e27ae9e63854bfe20c25b52bc2931654ae1d484 Mon Sep 17 00:00:00 2001 From: melina5656 <140602263+melina5656@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:12:00 +0800 Subject: [PATCH] Add TypeModelGeneric Test --- eng/testProjects.json | 1 + .../Properties/launchSettings.json | 4 + .../type-model-generic.cs | 23 + .../type/model/generic/Configuration.json | 11 + .../model/generic/_Type.Model.Generic.sln | 50 +++ .../src/Generated/Docs/GenericClient.xml | 113 +++++ .../generic/src/Generated/GenericClient.cs | 187 ++++++++ .../src/Generated/GenericClientOptions.cs | 16 + .../src/Generated/Internal/Argument.cs | 129 ++++++ .../Internal/ModelSerializationExtensions.cs | 398 ++++++++++++++++++ .../Internal/Utf8JsonRequestContent.cs | 55 +++ .../Models/Int32Type.Serialization.cs | 162 +++++++ .../generic/src/Generated/Models/Int32Type.cs | 43 ++ .../src/Generated/Models/Int32TypeKind.cs | 48 +++ .../Models/NumericType.Serialization.cs | 154 +++++++ .../src/Generated/Models/NumericType.cs | 82 ++++ ...TypeModelGenericClientBuilderExtensions.cs | 35 ++ .../Generated/TypeModelGenericModelFactory.cs | 28 ++ .../generic/src/Properties/AssemblyInfo.cs | 6 + .../generic/src/_Type.Model.Generic.csproj | 19 + .../Samples/Samples_GenericClient.cs | 140 ++++++ .../tests/_Type.Model.Generic.Tests.csproj | 19 + .../type/model/generic/tspCodeModel.json | 238 +++++++++++ .../type/model/generic/tspconfig.yaml | 3 + 24 files changed, 1964 insertions(+) create mode 100644 test/CadlRanchProjects.Tests/type-model-generic.cs create mode 100644 test/CadlRanchProjects/type/model/generic/Configuration.json create mode 100644 test/CadlRanchProjects/type/model/generic/_Type.Model.Generic.sln create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Docs/GenericClient.xml create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/GenericClient.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/GenericClientOptions.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Internal/Argument.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Internal/ModelSerializationExtensions.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Internal/Utf8JsonRequestContent.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.Serialization.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32TypeKind.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.Serialization.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericClientBuilderExtensions.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericModelFactory.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/Properties/AssemblyInfo.cs create mode 100644 test/CadlRanchProjects/type/model/generic/src/_Type.Model.Generic.csproj create mode 100644 test/CadlRanchProjects/type/model/generic/tests/Generated/Samples/Samples_GenericClient.cs create mode 100644 test/CadlRanchProjects/type/model/generic/tests/_Type.Model.Generic.Tests.csproj create mode 100644 test/CadlRanchProjects/type/model/generic/tspCodeModel.json create mode 100644 test/CadlRanchProjects/type/model/generic/tspconfig.yaml diff --git a/eng/testProjects.json b/eng/testProjects.json index 992f06833a9..941e433edff 100644 --- a/eng/testProjects.json +++ b/eng/testProjects.json @@ -7,6 +7,7 @@ "type/model/usage", "type/model/empty", "type/model/flatten", + "type/model/generic", "type/model/inheritance/single-discriminator", "type/model/inheritance/not-discriminated", "type/model/inheritance/enum-discriminator", diff --git a/src/AutoRest.CSharp/Properties/launchSettings.json b/src/AutoRest.CSharp/Properties/launchSettings.json index 2d9d0fc1e6a..5636b0b8f8a 100644 --- a/src/AutoRest.CSharp/Properties/launchSettings.json +++ b/src/AutoRest.CSharp/Properties/launchSettings.json @@ -892,6 +892,10 @@ "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\type\\model\\flatten\\src\\Generated -n" }, + "typespec-type/model/generic": { + "commandName": "Project", + "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\type\\model\\generic\\src\\Generated -n" + }, "typespec-type/model/inheritance/enum-discriminator": { "commandName": "Project", "commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\type\\model\\inheritance\\enum-discriminator\\src\\Generated -n" diff --git a/test/CadlRanchProjects.Tests/type-model-generic.cs b/test/CadlRanchProjects.Tests/type-model-generic.cs new file mode 100644 index 00000000000..4f679b373f3 --- /dev/null +++ b/test/CadlRanchProjects.Tests/type-model-generic.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using AutoRest.TestServer.Tests.Infrastructure; +using Azure; +using NUnit.Framework; +using _Type.Model.Generic.Models; +using _Type.Model.Generic; +using System.Collections.Generic; + +namespace CadlRanchProjects.Tests +{ + public class TypeModelGenericTests : CadlRanchTestBase + { + [Test] + public Task Type_Model_Generic_genericType() => Test(async (host) => + { + var values = new List { 1234 }; + var value = 1234; + var input = new Int32Type(values, value); + Response response = await new GenericClient(host, null).GenericTypeAsync(input); + Assert.AreEqual(204, response.Status); + }); + } +} diff --git a/test/CadlRanchProjects/type/model/generic/Configuration.json b/test/CadlRanchProjects/type/model/generic/Configuration.json new file mode 100644 index 00000000000..c16a6680932 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/Configuration.json @@ -0,0 +1,11 @@ +{ + "output-folder": ".", + "namespace": "_Type.Model.Generic", + "library-name": "_Type.Model.Generic", + "flavor": "azure", + "use-model-reader-writer": true, + "shared-source-folders": [ + "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Generator.Shared", + "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Azure.Core.Shared" + ] +} diff --git a/test/CadlRanchProjects/type/model/generic/_Type.Model.Generic.sln b/test/CadlRanchProjects/type/model/generic/_Type.Model.Generic.sln new file mode 100644 index 00000000000..c74c408303e --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/_Type.Model.Generic.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}") = "_Type.Model.Generic", "src\_Type.Model.Generic.csproj", "{28FF4005-4467-4E36-92E7-DEA27DEB1519}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_Type.Model.Generic.Tests", "tests\_Type.Model.Generic.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/type/model/generic/src/Generated/Docs/GenericClient.xml b/test/CadlRanchProjects/type/model/generic/src/Generated/Docs/GenericClient.xml new file mode 100644 index 00000000000..0002c267322 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Docs/GenericClient.xml @@ -0,0 +1,113 @@ + + + + + +This sample shows how to call GenericTypeAsync. + +This sample shows how to call GenericTypeAsync with all parameters. + + + + +This sample shows how to call GenericType. + +This sample shows how to call GenericType with all parameters. + + + + +This sample shows how to call GenericTypeAsync. + +This sample shows how to call GenericTypeAsync with all request content. + + + + +This sample shows how to call GenericType. + +This sample shows how to call GenericType with all request content. + + + + \ No newline at end of file diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClient.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClient.cs new file mode 100644 index 00000000000..f2b8919929a --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClient.cs @@ -0,0 +1,187 @@ +// 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 _Type.Model.Generic.Models; + +namespace _Type.Model.Generic +{ + // Data plane generated client. + /// Illustrates the model generic cases. + public partial class GenericClient + { + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + + /// 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 GenericClient. + public GenericClient() : this(new Uri("http://localhost:3000"), new GenericClientOptions()) + { + } + + /// Initializes a new instance of GenericClient. + /// TestServer endpoint. + /// The options for configuring the client. + /// is null. + public GenericClient(Uri endpoint, GenericClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); + options ??= new GenericClientOptions(); + + ClientDiagnostics = new ClientDiagnostics(options, true); + _pipeline = HttpPipelineBuilder.Build(options, Array.Empty(), Array.Empty(), new ResponseClassifier()); + _endpoint = endpoint; + } + + /// Generic type. + /// The to use. + /// The cancellation token to use. + /// is null. + /// + public virtual async Task GenericTypeAsync(Int32Type input, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(input, nameof(input)); + + using RequestContent content = input.ToRequestContent(); + RequestContext context = FromCancellationToken(cancellationToken); + Response response = await GenericTypeAsync(content, context).ConfigureAwait(false); + return response; + } + + /// Generic type. + /// The to use. + /// The cancellation token to use. + /// is null. + /// + public virtual Response GenericType(Int32Type input, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(input, nameof(input)); + + using RequestContent content = input.ToRequestContent(); + RequestContext context = FromCancellationToken(cancellationToken); + Response response = GenericType(content, context); + return response; + } + + /// + /// [Protocol Method] Generic type. + /// + /// + /// + /// 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 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. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual async Task GenericTypeAsync(RequestContent content, RequestContext context = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using var scope = ClientDiagnostics.CreateScope("GenericClient.GenericType"); + scope.Start(); + try + { + using HttpMessage message = CreateGenericTypeRequest(content, context); + return await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// + /// [Protocol Method] Generic type. + /// + /// + /// + /// 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 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. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + /// + public virtual Response GenericType(RequestContent content, RequestContext context = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using var scope = ClientDiagnostics.CreateScope("GenericClient.GenericType"); + scope.Start(); + try + { + using HttpMessage message = CreateGenericTypeRequest(content, context); + return _pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + internal HttpMessage CreateGenericTypeRequest(RequestContent content, RequestContext context) + { + var message = _pipeline.CreateMessage(context, ResponseClassifier204); + var request = message.Request; + request.Method = RequestMethod.Put; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/type/model/generic/genericType", false); + request.Uri = uri; + 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 _responseClassifier204; + private static ResponseClassifier ResponseClassifier204 => _responseClassifier204 ??= new StatusCodeClassifier(stackalloc ushort[] { 204 }); + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClientOptions.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClientOptions.cs new file mode 100644 index 00000000000..b8f304eff9f --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/GenericClientOptions.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using Azure.Core; + +namespace _Type.Model.Generic +{ + /// Client options for GenericClient. + public partial class GenericClientOptions : ClientOptions + { + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/Internal/Argument.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Internal/Argument.cs new file mode 100644 index 00000000000..57d1e7dd93b --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/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 _Type.Model.Generic +{ + 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/type/model/generic/src/Generated/Internal/ModelSerializationExtensions.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Internal/ModelSerializationExtensions.cs new file mode 100644 index 00000000000..7f0a394c3c2 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/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 _Type.Model.Generic +{ + 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/type/model/generic/src/Generated/Internal/Utf8JsonRequestContent.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Internal/Utf8JsonRequestContent.cs new file mode 100644 index 00000000000..a691bd03894 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/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 _Type.Model.Generic +{ + 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/type/model/generic/src/Generated/Models/Int32Type.Serialization.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.Serialization.cs new file mode 100644 index 00000000000..781a0db0f3e --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.Serialization.cs @@ -0,0 +1,162 @@ +// 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 _Type.Model.Generic.Models +{ + public partial class Int32Type : 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(Int32Type)} does not support writing '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind.ToString()); + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("value"u8); + writer.WriteNumberValue(Value); + 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(); + } + + Int32Type 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(Int32Type)} does not support reading '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInt32Type(document.RootElement, options); + } + + internal static Int32Type DeserializeInt32Type(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= ModelSerializationExtensions.WireOptions; + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Int32TypeKind kind = default; + IList values = default; + int value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary rawDataDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("kind"u8)) + { + kind = new Int32TypeKind(property.Value.GetString()); + continue; + } + if (property.NameEquals("values"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + values = array; + continue; + } + if (property.NameEquals("value"u8)) + { + value = property.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = rawDataDictionary; + return new Int32Type(values, value, serializedAdditionalRawData, kind); + } + + 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(Int32Type)} does not support writing '{options.Format}' format."); + } + } + + Int32Type 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 DeserializeInt32Type(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Int32Type)} 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 new Int32Type FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeInt32Type(document.RootElement); + } + + /// Convert into a . + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this, ModelSerializationExtensions.WireOptions); + return content; + } + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.cs new file mode 100644 index 00000000000..38cdb2fa41c --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32Type.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace _Type.Model.Generic.Models +{ + /// Facets an int32 field by the specified value ranges. + public partial class Int32Type : NumericType + { + /// Initializes a new instance of . + /// This model is used to perform facet processing on fields based on a specified range of values. + /// + /// is null. + public Int32Type(IEnumerable values, int value) : base(values, value) + { + Argument.AssertNotNull(values, nameof(values)); + } + + /// Initializes a new instance of . + /// This model is used to perform facet processing on fields based on a specified range of values. + /// + /// Keeps track of any properties unknown to the library. + /// The facet type. + internal Int32Type(IList values, int value, IDictionary serializedAdditionalRawData, Int32TypeKind kind) : base(values, value, serializedAdditionalRawData) + { + Kind = kind; + } + + /// Initializes a new instance of for deserialization. + internal Int32Type() + { + } + + /// The facet type. + public Int32TypeKind Kind { get; } = Int32TypeKind.Int32Values; + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32TypeKind.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32TypeKind.cs new file mode 100644 index 00000000000..c7c6a5df9bd --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/Int32TypeKind.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 _Type.Model.Generic.Models +{ + /// The Int32Type_kind. + public readonly partial struct Int32TypeKind : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public Int32TypeKind(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string Int32ValuesValue = "Int32Values"; + + /// Int32Values. + public static Int32TypeKind Int32Values { get; } = new Int32TypeKind(Int32ValuesValue); + /// Determines if two values are the same. + public static bool operator ==(Int32TypeKind left, Int32TypeKind right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(Int32TypeKind left, Int32TypeKind right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator Int32TypeKind(string value) => new Int32TypeKind(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is Int32TypeKind other && Equals(other); + /// + public bool Equals(Int32TypeKind 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/type/model/generic/src/Generated/Models/NumericType.Serialization.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.Serialization.cs new file mode 100644 index 00000000000..4d67581f1a0 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.Serialization.cs @@ -0,0 +1,154 @@ +// 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 _Type.Model.Generic.Models +{ + public partial class NumericType : 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(NumericType)} does not support writing '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("value"u8); + writer.WriteNumberValue(Value); + 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(); + } + + NumericType 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(NumericType)} does not support reading '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNumericType(document.RootElement, options); + } + + internal static NumericType DeserializeNumericType(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= ModelSerializationExtensions.WireOptions; + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList values = default; + int value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary rawDataDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("values"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + values = array; + continue; + } + if (property.NameEquals("value"u8)) + { + value = property.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = rawDataDictionary; + return new NumericType(values, value, 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(NumericType)} does not support writing '{options.Format}' format."); + } + } + + NumericType 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 DeserializeNumericType(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NumericType)} 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 NumericType FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeNumericType(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/type/model/generic/src/Generated/Models/NumericType.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.cs new file mode 100644 index 00000000000..73a808a7e34 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/Models/NumericType.cs @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace _Type.Model.Generic.Models +{ + /// The NumericType. + public partial class NumericType + { + /// + /// 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 protected IDictionary _serializedAdditionalRawData; + + /// Initializes a new instance of . + /// This model is used to perform facet processing on fields based on a specified range of values. + /// + /// is null. + public NumericType(IEnumerable values, int value) + { + Argument.AssertNotNull(values, nameof(values)); + + Values = values.ToList(); + Value = value; + } + + /// Initializes a new instance of . + /// This model is used to perform facet processing on fields based on a specified range of values. + /// + /// Keeps track of any properties unknown to the library. + internal NumericType(IList values, int value, IDictionary serializedAdditionalRawData) + { + Values = values; + Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal NumericType() + { + } + + /// This model is used to perform facet processing on fields based on a specified range of values. + public IList Values { get; } + /// Gets the value. + public int Value { get; } + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericClientBuilderExtensions.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericClientBuilderExtensions.cs new file mode 100644 index 00000000000..45363a98f29 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericClientBuilderExtensions.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 _Type.Model.Generic; + +namespace Microsoft.Extensions.Azure +{ + /// Extension methods to add to client builder. + public static partial class TypeModelGenericClientBuilderExtensions + { + /// Registers a instance. + /// The builder to register with. + /// TestServer endpoint. + public static IAzureClientBuilder AddGenericClient(this TBuilder builder, Uri endpoint) + where TBuilder : IAzureClientFactoryBuilder + { + return builder.RegisterClientFactory((options) => new GenericClient(endpoint, options)); + } + + /// Registers a instance. + /// The builder to register with. + /// The configuration values. + public static IAzureClientBuilder AddGenericClient(this TBuilder builder, TConfiguration configuration) + where TBuilder : IAzureClientFactoryBuilderWithConfiguration + { + return builder.RegisterClientFactory(configuration); + } + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericModelFactory.cs b/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericModelFactory.cs new file mode 100644 index 00000000000..878bc948ef0 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/Generated/TypeModelGenericModelFactory.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Linq; + +namespace _Type.Model.Generic.Models +{ + /// Model factory for models. + public static partial class TypeModelGenericModelFactory + { + /// Initializes a new instance of . + /// This model is used to perform facet processing on fields based on a specified range of values. + /// + /// The facet type. + /// A new instance for mocking. + public static Int32Type Int32Type(IEnumerable values = null, int value = default, Int32TypeKind kind = default) + { + values ??= new List(); + + return new Int32Type(values?.ToList(), value, serializedAdditionalRawData: null, kind); + } + } +} diff --git a/test/CadlRanchProjects/type/model/generic/src/Properties/AssemblyInfo.cs b/test/CadlRanchProjects/type/model/generic/src/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..4f3aceaff20 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/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("_Type.Model.Generic.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] diff --git a/test/CadlRanchProjects/type/model/generic/src/_Type.Model.Generic.csproj b/test/CadlRanchProjects/type/model/generic/src/_Type.Model.Generic.csproj new file mode 100644 index 00000000000..51af521e17b --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/src/_Type.Model.Generic.csproj @@ -0,0 +1,19 @@ + + + This is the _Type.Model.Generic client library for developing .NET applications with rich experience. + Azure SDK Code Generation _Type.Model.Generic for Azure Data Plane + 1.0.0-beta.1 + _Type.Model.Generic + $(RequiredTargetFrameworks) + true + + + + + + + + + + + diff --git a/test/CadlRanchProjects/type/model/generic/tests/Generated/Samples/Samples_GenericClient.cs b/test/CadlRanchProjects/type/model/generic/tests/Generated/Samples/Samples_GenericClient.cs new file mode 100644 index 00000000000..7900ecfed2a --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/tests/Generated/Samples/Samples_GenericClient.cs @@ -0,0 +1,140 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Identity; +using NUnit.Framework; +using _Type.Model.Generic.Models; + +namespace _Type.Model.Generic.Samples +{ + public partial class Samples_GenericClient + { + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_Generic_GenericType_ShortVersion() + { + GenericClient client = new GenericClient(); + + using RequestContent content = RequestContent.Create(new + { + kind = "Int32Values", + values = new object[] + { +1234 + }, + value = 1234, + }); + Response response = client.GenericType(content); + + Console.WriteLine(response.Status); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_Generic_GenericType_ShortVersion_Async() + { + GenericClient client = new GenericClient(); + + using RequestContent content = RequestContent.Create(new + { + kind = "Int32Values", + values = new object[] + { +1234 + }, + value = 1234, + }); + Response response = await client.GenericTypeAsync(content); + + Console.WriteLine(response.Status); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_Generic_GenericType_ShortVersion_Convenience() + { + GenericClient client = new GenericClient(); + + Int32Type input = new Int32Type(new int[] { 1234 }, 1234); + Response response = client.GenericType(input); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_Generic_GenericType_ShortVersion_Convenience_Async() + { + GenericClient client = new GenericClient(); + + Int32Type input = new Int32Type(new int[] { 1234 }, 1234); + Response response = await client.GenericTypeAsync(input); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_Generic_GenericType_AllParameters() + { + GenericClient client = new GenericClient(); + + using RequestContent content = RequestContent.Create(new + { + kind = "Int32Values", + values = new object[] + { +1234 + }, + value = 1234, + }); + Response response = client.GenericType(content); + + Console.WriteLine(response.Status); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_Generic_GenericType_AllParameters_Async() + { + GenericClient client = new GenericClient(); + + using RequestContent content = RequestContent.Create(new + { + kind = "Int32Values", + values = new object[] + { +1234 + }, + value = 1234, + }); + Response response = await client.GenericTypeAsync(content); + + Console.WriteLine(response.Status); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public void Example_Generic_GenericType_AllParameters_Convenience() + { + GenericClient client = new GenericClient(); + + Int32Type input = new Int32Type(new int[] { 1234 }, 1234); + Response response = client.GenericType(input); + } + + [Test] + [Ignore("Only validating compilation of examples")] + public async Task Example_Generic_GenericType_AllParameters_Convenience_Async() + { + GenericClient client = new GenericClient(); + + Int32Type input = new Int32Type(new int[] { 1234 }, 1234); + Response response = await client.GenericTypeAsync(input); + } + } +} diff --git a/test/CadlRanchProjects/type/model/generic/tests/_Type.Model.Generic.Tests.csproj b/test/CadlRanchProjects/type/model/generic/tests/_Type.Model.Generic.Tests.csproj new file mode 100644 index 00000000000..bdba1461bed --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/tests/_Type.Model.Generic.Tests.csproj @@ -0,0 +1,19 @@ + + + $(RequiredTargetFrameworks) + + $(NoWarn);CS1591 + + + + + + + + + + + + + + diff --git a/test/CadlRanchProjects/type/model/generic/tspCodeModel.json b/test/CadlRanchProjects/type/model/generic/tspCodeModel.json new file mode 100644 index 00000000000..fee64d15953 --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/tspCodeModel.json @@ -0,0 +1,238 @@ +{ + "$id": "1", + "Name": "Type.Model.Generic", + "ApiVersions": [], + "Enums": [ + { + "$id": "2", + "Kind": "enum", + "Name": "Int32Type_kind", + "ValueType": { + "$id": "3", + "Kind": "string" + }, + "Values": [ + { + "$id": "4", + "Name": "Int32Values", + "Value": "Int32Values", + "Description": "Int32Values" + } + ], + "CrossLanguageDefinitionId": "", + "Description": "The Int32Type_kind", + "IsExtensible": true, + "Usage": "Input,Json" + } + ], + "Models": [ + { + "$id": "5", + "Kind": "model", + "Name": "Int32Type", + "CrossLanguageDefinitionId": "Type.Model.Generic.Int32Type", + "Usage": "Input,Json", + "Description": "Facets an int32 field by the specified value ranges.", + "BaseModel": { + "$id": "6", + "Kind": "model", + "Name": "NumericType", + "CrossLanguageDefinitionId": "Type.Model.Generic.NumericType", + "Usage": "Input,Json", + "Properties": [ + { + "$id": "7", + "Name": "values", + "SerializedName": "values", + "Description": "This model is used to perform facet processing on fields based on a specified range of values.", + "Type": { + "$id": "8", + "Kind": "array", + "Name": "Array", + "ValueType": { + "$id": "9", + "Kind": "int32" + }, + "CrossLanguageDefinitionId": "TypeSpec.Array" + }, + "IsRequired": true, + "IsReadOnly": false + }, + { + "$id": "10", + "Name": "value", + "SerializedName": "value", + "Description": "", + "Type": { + "$id": "11", + "Kind": "int32" + }, + "IsRequired": true, + "IsReadOnly": false + } + ] + }, + "Properties": [ + { + "$id": "12", + "Name": "kind", + "SerializedName": "kind", + "Description": "The facet type.", + "Type": { + "$id": "13", + "Kind": "constant", + "ValueType": { + "$ref": "2" + }, + "Value": "Int32Values" + }, + "IsRequired": true, + "IsReadOnly": false + } + ] + }, + { + "$ref": "6" + } + ], + "Clients": [ + { + "$id": "14", + "Name": "GenericClient", + "Description": "Illustrates the model generic cases.", + "Operations": [ + { + "$id": "15", + "Name": "genericType", + "ResourceName": "Generic", + "Accessibility": "public", + "Parameters": [ + { + "$id": "16", + "Name": "host", + "NameInRequest": "host", + "Description": "TestServer endpoint", + "Type": { + "$id": "17", + "Kind": "string" + }, + "Location": "Uri", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": true, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Client", + "DefaultValue": { + "$id": "18", + "Type": { + "$id": "19", + "Kind": "string" + }, + "Value": "http://localhost:3000" + } + }, + { + "$id": "20", + "Name": "input", + "NameInRequest": "input", + "Type": { + "$ref": "5" + }, + "Location": "Body", + "IsRequired": true, + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsEndpoint": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Method" + }, + { + "$id": "21", + "Name": "contentType", + "NameInRequest": "Content-Type", + "Type": { + "$id": "22", + "Kind": "string" + }, + "Location": "Header", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": true, + "IsRequired": true, + "IsEndpoint": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Constant", + "DefaultValue": { + "$id": "23", + "Type": { + "$ref": "22" + }, + "Value": "application/json" + } + }, + { + "$id": "24", + "Name": "accept", + "NameInRequest": "Accept", + "Type": { + "$id": "25", + "Kind": "string" + }, + "Location": "Header", + "IsApiVersion": false, + "IsResourceParameter": false, + "IsContentType": false, + "IsRequired": true, + "IsEndpoint": false, + "SkipUrlEncoding": false, + "Explode": false, + "Kind": "Constant", + "DefaultValue": { + "$id": "26", + "Type": { + "$ref": "25" + }, + "Value": "application/json" + } + } + ], + "Responses": [ + { + "$id": "27", + "StatusCodes": [ + 204 + ], + "BodyMediaType": "Json", + "Headers": [], + "IsErrorResponse": false + } + ], + "HttpMethod": "PUT", + "RequestBodyMediaType": "Json", + "Uri": "{host}", + "Path": "/type/model/generic/genericType", + "RequestMediaTypes": [ + "application/json" + ], + "BufferResponse": true, + "GenerateProtocolMethod": true, + "GenerateConvenienceMethod": true + } + ], + "Protocol": { + "$id": "28" + }, + "Parameters": [ + { + "$ref": "16" + } + ] + } + ] +} diff --git a/test/CadlRanchProjects/type/model/generic/tspconfig.yaml b/test/CadlRanchProjects/type/model/generic/tspconfig.yaml new file mode 100644 index 00000000000..430ab81cacc --- /dev/null +++ b/test/CadlRanchProjects/type/model/generic/tspconfig.yaml @@ -0,0 +1,3 @@ +options: + "@azure-tools/typespec-csharp": + namespace: _Type.Model.Generic