From b4f5cd7d6da74d859ccbf8b86cd5598edc32d426 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 22 Oct 2025 10:39:56 -0700 Subject: [PATCH 1/8] minor: added long path support to prerequisite --- packages/http-client-csharp/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/http-client-csharp/CONTRIBUTING.md b/packages/http-client-csharp/CONTRIBUTING.md index d32813e3357..53518283b9c 100644 --- a/packages/http-client-csharp/CONTRIBUTING.md +++ b/packages/http-client-csharp/CONTRIBUTING.md @@ -22,6 +22,7 @@ Before you begin, ensure you have the following installed: - [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [Git](https://git-scm.com/) - [PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell) (version 7.0 or higher, for advanced testing and code generation scenarios) +- [Long Path Support](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#registry-setting-to-enable-long-paths) (Windows only required to avoid path length limitations during development) ## Getting Started From 6606677831e70cfc6932627e27168ee5ec5a5e8d Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 21 Jan 2026 11:38:35 -0800 Subject: [PATCH 2/8] csv encoding --- .../emitter/src/lib/type-converter.ts | 1 + .../emitter/src/type/input-type.ts | 1 + .../MrwSerializationTypeDefinition.cs | 163 +++++++++- .../src/InputTypes/InputModelProperty.cs | 5 +- .../InputModelPropertyConverter.cs | 8 +- .../src/Primitives/PropertyWireInformation.cs | 5 +- .../Http/Encode/Array/EncodeArrayTests.cs | 62 ++++ .../TestProjects.Spector.Tests.csproj | 1 + .../src/Generated/ArrayClient.RestClient.cs | 11 + .../encode/array/src/Generated/ArrayClient.cs | 33 +- .../array/src/Generated/ArrayClientOptions.cs | 1 + .../src/Generated/EncodeArrayModelFactory.cs | 42 ++- .../array/src/Generated/Internal/Argument.cs | 71 +++++ .../Internal/CancellationTokenExtensions.cs | 14 + .../Internal/ChangeTrackingDictionary.cs | 186 +++++++++++ .../Generated/Internal/ChangeTrackingList.cs | 165 ++++++++++ .../Internal/ClientPipelineExtensions.cs | 67 ++++ .../Generated/Internal/ClientUriBuilder.cs | 137 ++++++++ .../Internal/CodeGenMemberAttribute.cs | 17 + .../Internal/CodeGenSerializationAttribute.cs | 45 +++ .../Internal/CodeGenSuppressAttribute.cs | 26 ++ .../Internal/CodeGenTypeAttribute.cs | 21 ++ .../src/Generated/Internal/ErrorResult.cs | 24 ++ .../Internal/ModelSerializationExtensions.cs | 265 ++++++++++++++++ .../Generated/Internal/SerializationFormat.cs | 46 +++ .../src/Generated/Internal/TypeFormatters.cs | 177 +++++++++++ ...mmaDelimitedArrayProperty.Serialization.cs | 145 ++++++++- .../Models/CommaDelimitedArrayProperty.cs | 28 +- .../Generated/Models/Encode_ArrayContext.cs | 4 + ...ineDelimitedArrayProperty.Serialization.cs | 145 ++++++++- .../Models/NewlineDelimitedArrayProperty.cs | 28 +- ...ipeDelimitedArrayProperty.Serialization.cs | 145 ++++++++- .../Models/PipeDelimitedArrayProperty.cs | 28 +- ...aceDelimitedArrayProperty.Serialization.cs | 145 ++++++++- .../Models/SpaceDelimitedArrayProperty.cs | 28 +- .../src/Generated/Property.RestClient.cs | 74 +++++ .../encode/array/src/Generated/Property.cs | 293 ++++++++++++++++-- .../http/encode/array/tspCodeModel.json | 12 +- 38 files changed, 2575 insertions(+), 94 deletions(-) create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector.Tests/Http/Encode/Array/EncodeArrayTests.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs diff --git a/packages/http-client-csharp/emitter/src/lib/type-converter.ts b/packages/http-client-csharp/emitter/src/lib/type-converter.ts index f6b31db5578..56760039ab8 100644 --- a/packages/http-client-csharp/emitter/src/lib/type-converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/type-converter.ts @@ -269,6 +269,7 @@ function fromSdkModelProperty( serializationOptions: sdkProperty.serializationOptions, // A property is defined to be metadata if it is marked `@header`, `@cookie`, `@query`, `@path`. isHttpMetadata: isHttpMetadata(sdkContext, sdkProperty), + encode: sdkProperty.encode, } as InputModelProperty; if (property) { diff --git a/packages/http-client-csharp/emitter/src/type/input-type.ts b/packages/http-client-csharp/emitter/src/type/input-type.ts index b4008677dd8..922aa4a8063 100644 --- a/packages/http-client-csharp/emitter/src/type/input-type.ts +++ b/packages/http-client-csharp/emitter/src/type/input-type.ts @@ -181,6 +181,7 @@ export interface InputModelProperty extends InputPropertyTypeBase { serializationOptions: SerializationOptions; flatten: boolean; isHttpMetadata: boolean; + encode?: string; } export type InputProperty = InputModelProperty | InputParameter; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs index 4a36125f9e1..4b65a80c4c4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs @@ -1290,11 +1290,26 @@ private MethodBodyStatement[] DeserializeProperty( bool useCustomDeserializationHook = false; var serializationFormat = wireInfo.SerializationFormat; var propertyVarReference = variableExpression; - var deserializationStatements = new MethodBodyStatement[2] + + MethodBodyStatement[] deserializationStatements; + + // Check for encoded arrays and use custom deserialization logic + if (!string.IsNullOrEmpty(wireInfo.Encode) && (propertyType.IsList || propertyType.IsArray)) { - DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), - propertyVarReference.Assign(value).Terminate() - }; + deserializationStatements = CreateEncodedArrayDeserializationStatements( + propertyType, + propertyVarReference, + jsonProperty, + wireInfo.Encode); + } + else + { + deserializationStatements = new MethodBodyStatement[2] + { + DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), + propertyVarReference.Assign(value).Terminate() + }; + } foreach (var attribute in serializationAttributes) { @@ -1634,6 +1649,15 @@ private MethodBodyStatement CreateWritePropertyStatement( // Generate the serialization statements for the property var serializationStatement = CreateSerializationStatement(propertyType, propertyExpression, propertySerializationFormat, propertySerializationName); + // Check for encoded arrays and override the serialization statement + if (!string.IsNullOrEmpty(wireInfo.Encode) && (propertyType.IsList || propertyType.IsArray)) + { + serializationStatement = CreateEncodedArraySerializationStatement( + propertyType, + propertyExpression, + wireInfo.Encode); + } + // Check for custom serialization hooks foreach (var attribute in _model.CustomCodeView?.Attributes .Where(a => a.Type.Name == CodeGenAttributes.CodeGenSerializationAttributeName) ?? []) @@ -1810,6 +1834,137 @@ private MethodBodyStatement CreateListSerialization( }; } + private MethodBodyStatement CreateEncodedArraySerializationStatement( + CSharpType propertyType, + ValueExpression propertyExpression, + string encoding) + { + // Get the delimiter based on the encoding type + var delimiter = encoding switch + { + "commaDelimited" => ",", + "spaceDelimited" => " ", + "pipeDelimited" => "|", + "newlineDelimited" => "\n", + _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") + }; + + // Get element type for string conversion + var elementType = propertyType.IsArray ? propertyType.ElementType : propertyType.Arguments[0]; + + // Build the serialization expression based on element type + ValueExpression stringJoinExpression; + if (elementType.IsFrameworkType && elementType.FrameworkType == typeof(string)) + { + // For string arrays, use string.Join directly + // string.Join(",", array) + stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), propertyExpression); + } + else + { + // For non-string arrays, convert each element to string first + // string.Join(",", array.Select(x => x?.ToString() ?? "")) + var x = new VariableExpression(typeof(object), "x"); + var selectExpression = propertyExpression.Invoke("Select", + new FuncExpression([x.Declaration], new TernaryConditionalExpression( + x.Equal(Null), + Literal(""), + x.Invoke("ToString")))); + stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), selectExpression); + } + + // writer.WriteStringValue(stringJoinExpression) + return _utf8JsonWriterSnippet.WriteStringValue(stringJoinExpression); + } + + private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( + CSharpType propertyType, + VariableExpression variableExpression, + ScopedApi jsonProperty, + string encoding) + { + var delimiter = encoding switch + { + "commaDelimited" => ",", + "spaceDelimited" => " ", + "pipeDelimited" => "|", + "newlineDelimited" => "\n", + _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") + }; + var elementType = propertyType.IsArray ? propertyType.ElementType : propertyType.Arguments[0]; + var delimiterChar = Literal(delimiter.ToCharArray()[0]); + var isStringElement = elementType.IsFrameworkType && elementType.FrameworkType == typeof(string); + + var getStringStatement = Declare("stringValue", typeof(string), jsonProperty.Value().GetString(), out var stringValueVar); + var isNullOrEmptyCheck = Static().Invoke("IsNullOrEmpty", stringValueVar); + + MethodBodyStatement createArrayStatement; + + if (isStringElement) + { + var splitResult = stringValueVar.Invoke("Split", delimiterChar); + if (propertyType.IsArray) + { + var emptyExpression = new NewArrayExpression(elementType); + var conditionalExpression = new TernaryConditionalExpression( + isNullOrEmptyCheck, emptyExpression, splitResult); + createArrayStatement = variableExpression.Assign(conditionalExpression).Terminate(); + } + else if (propertyType.IsList) + { + var emptyExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType)); + var populatedExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), splitResult); + var conditionalExpression = new TernaryConditionalExpression( + isNullOrEmptyCheck, emptyExpression, populatedExpression); + createArrayStatement = variableExpression.Assign(conditionalExpression).Terminate(); + } + else + { + var listExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), splitResult); + var conditionalExpression = new TernaryConditionalExpression( + isNullOrEmptyCheck, New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType)), listExpression); + createArrayStatement = variableExpression.Assign(New.Instance(propertyType, conditionalExpression)).Terminate(); + } + } + else + { + var splitExpression = new TernaryConditionalExpression( + isNullOrEmptyCheck, + new NewArrayExpression(typeof(string)), + stringValueVar.Invoke("Split", delimiterChar)); + + var s = new VariableExpression(typeof(string), "s"); + var trimmedS = s.Invoke("Trim"); + + var parseExpression = elementType.IsFrameworkType + ? elementType.FrameworkType.Name switch + { + nameof(Int32) => Static().Invoke("Parse", trimmedS), + nameof(Int64) => Static().Invoke("Parse", trimmedS), + nameof(Double) => Static().Invoke("Parse", trimmedS), + nameof(Single) => Static().Invoke("Parse", trimmedS), + nameof(Boolean) => Static().Invoke("Parse", trimmedS), + _ => throw new InvalidOperationException($"Unsupported primitive type: {elementType.FrameworkType}") + } + : Static(elementType).Invoke("Parse", trimmedS); // Custom types + + var selectExpression = splitExpression.Invoke("Select", + new FuncExpression([s.Declaration], parseExpression)); + + var finalExpression = propertyType.IsArray + ? selectExpression.Invoke("ToArray") + : propertyType.IsList + ? New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), selectExpression) + : New.Instance(propertyType, selectExpression); + createArrayStatement = variableExpression.Assign(finalExpression).Terminate(); + } + return + [ + getStringStatement, + createArrayStatement + ]; + } + private MethodBodyStatement CreateDictionarySerialization( DictionaryExpression dictionary, SerializationFormat serializationFormat, diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs index e0e0f3126f1..719be7ed28e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs @@ -18,7 +18,8 @@ public InputModelProperty( bool isHttpMetadata, bool isApiVersion, InputConstant? defaultValue, - InputSerializationOptions serializationOptions) + InputSerializationOptions serializationOptions, + string? encode = null) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName, isApiVersion, defaultValue) { Name = name; @@ -30,11 +31,13 @@ public InputModelProperty( IsDiscriminator = isDiscriminator; IsHttpMetadata = isHttpMetadata; SerializationOptions = serializationOptions; + Encode = encode; } public bool IsDiscriminator { get; internal set; } public InputSerializationOptions? SerializationOptions { get; internal set; } public bool IsHttpMetadata { get; internal set; } + public string? Encode { get; internal set; } /// /// Updates the properties of the input model property. diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs index 85ab88453c7..a9c62ac76cb 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs @@ -46,7 +46,8 @@ internal static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader rea isHttpMetadata: false, isApiVersion: false, defaultValue: null, - serializationOptions: null!); + serializationOptions: null!, + encode: null); resolver.AddReference(id, property); string? kind = null; @@ -63,6 +64,7 @@ internal static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader rea bool isDiscriminator = false; IReadOnlyList? decorators = null; InputSerializationOptions? serializationOptions = null; + string? encode = null; while (reader.TokenType != JsonTokenType.EndObject) { @@ -81,7 +83,8 @@ internal static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader rea || reader.TryReadString("serializedName", ref serializedName) || reader.TryReadBoolean("isApiVersion", ref isApiVersion) || reader.TryReadComplexType("defaultValue", options, ref defaultValue) - || reader.TryReadComplexType("serializationOptions", options, ref serializationOptions); + || reader.TryReadComplexType("serializationOptions", options, ref serializationOptions) + || reader.TryReadString("encode", ref encode); if (!isKnownProperty) { @@ -103,6 +106,7 @@ internal static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader rea property.SerializedName = serializedName ?? serializationOptions?.Json?.Name ?? name; property.IsApiVersion = isApiVersion; property.DefaultValue = defaultValue; + property.Encode = encode; return property; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs index 336f4d3968f..a6fa1a37d97 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs @@ -14,8 +14,9 @@ public class PropertyWireInformation : WireInformation public bool IsNullable { get; } public bool IsDiscriminator { get; } public bool IsHttpMetadata { get; } + public string? Encode { get; } internal FormattableString? Description { get; } - public PropertyWireInformation(SerializationFormat serializationFormat, bool isRequired, bool isReadOnly, bool isNullable, bool isDiscriminator, string serializedName, bool isHttpMetadata) + public PropertyWireInformation(SerializationFormat serializationFormat, bool isRequired, bool isReadOnly, bool isNullable, bool isDiscriminator, string serializedName, bool isHttpMetadata, string? encode = null) : base(serializationFormat, serializedName) { IsRequired = isRequired; @@ -23,6 +24,7 @@ public PropertyWireInformation(SerializationFormat serializationFormat, bool isR IsNullable = isNullable; IsDiscriminator = isDiscriminator; IsHttpMetadata = isHttpMetadata; + Encode = encode; } /// @@ -39,6 +41,7 @@ internal PropertyWireInformation(InputProperty inputProperty) IsHttpMetadata = modelProperty != null && modelProperty.IsHttpMetadata; IsNullable = inputProperty.Type is InputNullableType; IsDiscriminator = modelProperty != null && modelProperty.IsDiscriminator; + Encode = modelProperty?.Encode; Description = DocHelpers.GetFormattableDescription(inputProperty.Summary, inputProperty.Doc); } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector.Tests/Http/Encode/Array/EncodeArrayTests.cs b/packages/http-client-csharp/generator/TestProjects/Spector.Tests/Http/Encode/Array/EncodeArrayTests.cs new file mode 100644 index 00000000000..fda1d9d1423 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector.Tests/Http/Encode/Array/EncodeArrayTests.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.Collections.Generic; +using System.Threading.Tasks; +using Encode._Array; +using Encode._Array._Property; +using NUnit.Framework; + +namespace TestProjects.Spector.Tests.Http.Encode.Array +{ + public class EncodeArrayTests : SpectorTestBase + { + [SpectorTest] + public Task CommaDelimited() => Test(async (host) => + { + var testData = new List { "blue", "red", "green" }; + var body = new CommaDelimitedArrayProperty(testData); + + ClientResult result = await new ArrayClient(host, null).GetPropertyClient().CommaDelimitedAsync(body); + Assert.AreEqual(200, result.GetRawResponse().Status); + Assert.AreEqual(testData, result.Value.Value); + }); + + [SpectorTest] + public Task SpaceDelimited() => Test(async (host) => + { + var testData = new List { "blue", "red", "green" }; + var body = new SpaceDelimitedArrayProperty(testData); + + ClientResult result = await new ArrayClient(host, null).GetPropertyClient().SpaceDelimitedAsync(body); + Assert.AreEqual(200, result.GetRawResponse().Status); + Assert.AreEqual(testData, result.Value.Value); + }); + + [SpectorTest] + public Task PipeDelimited() => Test(async (host) => + { + var testData = new List { "blue", "red", "green" }; + var body = new PipeDelimitedArrayProperty(testData); + + ClientResult result = await new ArrayClient(host, null).GetPropertyClient().PipeDelimitedAsync(body); + Assert.AreEqual(200, result.GetRawResponse().Status); + Assert.AreEqual(testData, result.Value.Value); + }); + + [SpectorTest] + public Task NewlineDelimited() => Test(async (host) => + { + var testData = new List { "blue", "red", "green" }; + var body = new NewlineDelimitedArrayProperty(testData); + + ClientResult result = await new ArrayClient(host, null).GetPropertyClient().NewlineDelimitedAsync(body); + Assert.AreEqual(200, result.GetRawResponse().Status); + Assert.AreEqual(testData, result.Value.Value); + }); + + + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector.Tests/TestProjects.Spector.Tests.csproj b/packages/http-client-csharp/generator/TestProjects/Spector.Tests/TestProjects.Spector.Tests.csproj index 62e00182caf..abd55b4bcea 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector.Tests/TestProjects.Spector.Tests.csproj +++ b/packages/http-client-csharp/generator/TestProjects/Spector.Tests/TestProjects.Spector.Tests.csproj @@ -32,6 +32,7 @@ + diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs new file mode 100644 index 00000000000..d94692a69fe --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs @@ -0,0 +1,11 @@ +// + +#nullable disable + +namespace Encode._Array +{ + /// + public partial class ArrayClient + { + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs index 55ae5b366f0..b175ca06967 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs @@ -4,18 +4,43 @@ using System; using System.ClientModel.Primitives; +using System.Threading; using Encode._Array._Property; namespace Encode._Array { + /// Test for encode decorator on array. public partial class ArrayClient { - public ArrayClient() : this(new Uri("http://localhost:3000"), new ArrayClientOptions()) => throw null; + private readonly Uri _endpoint; + private Property _cachedProperty; - public ArrayClient(Uri endpoint, ArrayClientOptions options) => throw null; + /// Initializes a new instance of ArrayClient. + public ArrayClient() : this(new Uri("http://localhost:3000"), new ArrayClientOptions()) + { + } - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of ArrayClient. + /// Service endpoint. + /// The options for configuring the client. + /// is null. + public ArrayClient(Uri endpoint, ArrayClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); - public virtual Property GetPropertyClient() => throw null; + options ??= new ArrayClientOptions(); + + _endpoint = endpoint; + Pipeline = ClientPipeline.Create(options, Array.Empty(), new PipelinePolicy[] { new UserAgentPolicy(typeof(ArrayClient).Assembly) }, Array.Empty()); + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// Initializes a new instance of Property. + public virtual Property GetPropertyClient() + { + return Volatile.Read(ref _cachedProperty) ?? Interlocked.CompareExchange(ref _cachedProperty, new Property(Pipeline, _endpoint), null) ?? _cachedProperty; + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs index 392d2e67a55..abbd7e7d76a 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs @@ -6,6 +6,7 @@ namespace Encode._Array { + /// Client options for . public partial class ArrayClientOptions : ClientPipelineOptions { } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs index f1b065009ce..a6207ca2740 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs @@ -3,17 +3,51 @@ #nullable disable using System.Collections.Generic; +using System.Linq; namespace Encode._Array { + /// A factory class for creating instances of the models for mocking. public static partial class EncodeArrayModelFactory { - public static CommaDelimitedArrayProperty CommaDelimitedArrayProperty(IEnumerable value = default) => throw null; + /// The CommaDelimitedArrayProperty. + /// + /// A new instance for mocking. + public static CommaDelimitedArrayProperty CommaDelimitedArrayProperty(IEnumerable value = default) + { + value ??= new ChangeTrackingList(); - public static SpaceDelimitedArrayProperty SpaceDelimitedArrayProperty(IEnumerable value = default) => throw null; + return new CommaDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); + } - public static PipeDelimitedArrayProperty PipeDelimitedArrayProperty(IEnumerable value = default) => throw null; + /// The SpaceDelimitedArrayProperty. + /// + /// A new instance for mocking. + public static SpaceDelimitedArrayProperty SpaceDelimitedArrayProperty(IEnumerable value = default) + { + value ??= new ChangeTrackingList(); - public static NewlineDelimitedArrayProperty NewlineDelimitedArrayProperty(IEnumerable value = default) => throw null; + return new SpaceDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); + } + + /// The PipeDelimitedArrayProperty. + /// + /// A new instance for mocking. + public static PipeDelimitedArrayProperty PipeDelimitedArrayProperty(IEnumerable value = default) + { + value ??= new ChangeTrackingList(); + + return new PipeDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); + } + + /// The NewlineDelimitedArrayProperty. + /// + /// A new instance for mocking. + public static NewlineDelimitedArrayProperty NewlineDelimitedArrayProperty(IEnumerable value = default) + { + value ??= new ChangeTrackingList(); + + return new NewlineDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs new file mode 100644 index 00000000000..538eb79fc39 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs @@ -0,0 +1,71 @@ +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Encode._Array +{ + internal static partial class Argument + { + /// The value. + /// The name. + public static void AssertNotNull(T value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + } + + /// The value. + /// The name. + public static void AssertNotNull(T? value, string name) + where T : struct + { + if (!value.HasValue) + { + throw new ArgumentNullException(name); + } + } + + /// The value. + /// The 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); + } + } + + /// The value. + /// The 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); + } + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs new file mode 100644 index 00000000000..5ff23ae7999 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs @@ -0,0 +1,14 @@ +// + +#nullable disable + +using System.ClientModel.Primitives; +using System.Threading; + +namespace Encode._Array +{ + internal static partial class CancellationTokenExtensions + { + public static RequestOptions ToRequestOptions(this CancellationToken cancellationToken) => cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs new file mode 100644 index 00000000000..b406a43171d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs @@ -0,0 +1,186 @@ +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Encode._Array +{ + internal partial class ChangeTrackingDictionary : IDictionary, IReadOnlyDictionary + where TKey : notnull + { + private IDictionary _innerDictionary; + + public ChangeTrackingDictionary() + { + } + + /// The inner dictionary. + public ChangeTrackingDictionary(IDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(dictionary); + } + + /// The inner dictionary. + public ChangeTrackingDictionary(IReadOnlyDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(); + foreach (var pair in dictionary) + { + _innerDictionary.Add(pair); + } + } + + /// Gets the IsUndefined. + public bool IsUndefined => _innerDictionary == null; + + /// Gets the Count. + public int Count => IsUndefined ? 0 : EnsureDictionary().Count; + + /// Gets the IsReadOnly. + public bool IsReadOnly => IsUndefined ? false : EnsureDictionary().IsReadOnly; + + /// Gets the Keys. + public ICollection Keys => IsUndefined ? Array.Empty() : EnsureDictionary().Keys; + + /// Gets the Values. + public ICollection Values => IsUndefined ? Array.Empty() : EnsureDictionary().Values; + + /// Gets or sets the value associated with the specified key. + public TValue this[TKey key] + { + get + { + if (IsUndefined) + { + throw new KeyNotFoundException(nameof(key)); + } + return EnsureDictionary()[key]; + } + set + { + EnsureDictionary()[key] = value; + } + } + + /// Gets the Keys. + IEnumerable IReadOnlyDictionary.Keys => Keys; + + /// Gets the Values. + IEnumerable IReadOnlyDictionary.Values => Values; + + public IEnumerator> GetEnumerator() + { + if (IsUndefined) + { + IEnumerator> enumerateEmpty() + { + yield break; + } + return enumerateEmpty(); + } + return EnsureDictionary().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// The item to add. + public void Add(KeyValuePair item) + { + EnsureDictionary().Add(item); + } + + public void Clear() + { + EnsureDictionary().Clear(); + } + + /// The item to search for. + public bool Contains(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Contains(item); + } + + /// The array to copy. + /// The index. + public void CopyTo(KeyValuePair[] array, int index) + { + if (IsUndefined) + { + return; + } + EnsureDictionary().CopyTo(array, index); + } + + /// The item to remove. + public bool Remove(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(item); + } + + /// The key. + /// The value to add. + public void Add(TKey key, TValue value) + { + EnsureDictionary().Add(key, value); + } + + /// The key to search for. + public bool ContainsKey(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().ContainsKey(key); + } + + /// The key. + public bool Remove(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(key); + } + + /// The key to search for. + /// The value. + 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/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs new file mode 100644 index 00000000000..b46ae0c8c5b --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs @@ -0,0 +1,165 @@ +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Encode._Array +{ + internal partial class ChangeTrackingList : IList, IReadOnlyList + { + private IList _innerList; + + public ChangeTrackingList() + { + } + + /// The inner list. + public ChangeTrackingList(IList innerList) + { + if (innerList != null) + { + _innerList = innerList; + } + } + + /// The inner list. + public ChangeTrackingList(IReadOnlyList innerList) + { + if (innerList != null) + { + _innerList = innerList.ToList(); + } + } + + /// Gets the IsUndefined. + public bool IsUndefined => _innerList == null; + + /// Gets the Count. + public int Count => IsUndefined ? 0 : EnsureList().Count; + + /// Gets the IsReadOnly. + public bool IsReadOnly => IsUndefined ? false : EnsureList().IsReadOnly; + + /// Gets or sets the value associated with the specified key. + 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(); + } + + /// The item to add. + public void Add(T item) + { + EnsureList().Add(item); + } + + public void Clear() + { + EnsureList().Clear(); + } + + /// The item. + public bool Contains(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Contains(item); + } + + /// The array to copy to. + /// The array index. + public void CopyTo(T[] array, int arrayIndex) + { + if (IsUndefined) + { + return; + } + EnsureList().CopyTo(array, arrayIndex); + } + + /// The item. + public bool Remove(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Remove(item); + } + + /// The item. + public int IndexOf(T item) + { + if (IsUndefined) + { + return -1; + } + return EnsureList().IndexOf(item); + } + + /// The inner list. + /// The item. + public void Insert(int index, T item) + { + EnsureList().Insert(index, item); + } + + /// The inner list. + 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/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs new file mode 100644 index 00000000000..0b31f807b50 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs @@ -0,0 +1,67 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +namespace Encode._Array +{ + internal static partial class ClientPipelineExtensions + { + public static async ValueTask ProcessMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + await pipeline.SendAsync(message).ConfigureAwait(false); + + if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) + { + throw await ClientResultException.CreateAsync(message.Response).ConfigureAwait(false); + } + + PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); + return response; + } + + public static PipelineResponse ProcessMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + pipeline.Send(message); + + if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) + { + throw new ClientResultException(message.Response); + } + + PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); + return response; + } + + public static async ValueTask> ProcessHeadAsBoolMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + PipelineResponse response = await pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false); + switch (response.Status) + { + case >= 200 and < 300: + return ClientResult.FromValue(true, response); + case >= 400 and < 500: + return ClientResult.FromValue(false, response); + default: + return new ErrorResult(response, new ClientResultException(response)); + } + } + + public static ClientResult ProcessHeadAsBoolMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) + { + PipelineResponse response = pipeline.ProcessMessage(message, options); + switch (response.Status) + { + case >= 200 and < 300: + return ClientResult.FromValue(true, response); + case >= 400 and < 500: + return ClientResult.FromValue(false, response); + default: + return new ErrorResult(response, new ClientResultException(response)); + } + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs new file mode 100644 index 00000000000..b8f39fce3d1 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs @@ -0,0 +1,137 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Encode._Array +{ + internal partial class ClientUriBuilder + { + private UriBuilder _uriBuilder; + private StringBuilder _pathAndQuery; + private int _pathLength; + + public ClientUriBuilder() + { + } + + private UriBuilder UriBuilder => _uriBuilder ??= new UriBuilder(); + + private StringBuilder PathAndQuery => _pathAndQuery ??= new StringBuilder(); + + public void Reset(Uri uri) + { + _uriBuilder = new UriBuilder(uri); + PathAndQuery.Clear(); + PathAndQuery.Append(UriBuilder.Path); + _pathLength = PathAndQuery.Length; + PathAndQuery.Append(UriBuilder.Query); + } + + public void AppendPath(string value, bool escape) + { + if (escape) + { + value = Uri.EscapeDataString(value); + } + if (_pathLength > 0 && PathAndQuery[_pathLength - 1] == '/' && value[0] == '/') + { + PathAndQuery.Remove(_pathLength - 1, 1); + _pathLength = _pathLength - 1; + } + PathAndQuery.Insert(_pathLength, value); + _pathLength = _pathLength + value.Length; + } + + public void AppendPath(bool value, bool escape = false) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(float value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(double value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(int value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(byte[] value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(DateTimeOffset value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(TimeSpan value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); + + public void AppendPath(Guid value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPath(long value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); + + public void AppendPathDelimited(IEnumerable value, string delimiter, SerializationFormat format = SerializationFormat.Default, bool escape = true) + { + delimiter ??= ","; + IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); + AppendPath(string.Join(delimiter, stringValues), escape); + } + + public void AppendQuery(string name, string value, bool escape) + { + if (PathAndQuery.Length == _pathLength) + { + PathAndQuery.Append('?'); + } + if (PathAndQuery.Length > _pathLength && PathAndQuery[PathAndQuery.Length - 1] != '?') + { + PathAndQuery.Append('&'); + } + if (escape) + { + value = Uri.EscapeDataString(value); + } + PathAndQuery.Append(name); + PathAndQuery.Append('='); + PathAndQuery.Append(value); + } + + public void AppendQuery(string name, bool value, bool escape = false) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, float value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, DateTimeOffset value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, TimeSpan value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, double value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, decimal value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, int value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, long value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, TimeSpan value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQuery(string name, byte[] value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); + + public void AppendQuery(string name, Guid value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); + + public void AppendQueryDelimited(string name, IEnumerable value, string delimiter, SerializationFormat format = SerializationFormat.Default, bool escape = true) + { + delimiter ??= ","; + IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); + AppendQuery(name, string.Join(delimiter, stringValues), escape); + } + + public Uri ToUri() + { + UriBuilder.Path = PathAndQuery.ToString(0, _pathLength); + if (PathAndQuery.Length > _pathLength) + { + UriBuilder.Query = PathAndQuery.ToString(_pathLength + 1, PathAndQuery.Length - _pathLength - 1); + } + if (PathAndQuery.Length == _pathLength) + { + UriBuilder.Query = ""; + } + return UriBuilder.Uri; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs new file mode 100644 index 00000000000..044dfe314c5 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs @@ -0,0 +1,17 @@ +// + +#nullable disable + +using System; + +namespace Microsoft.TypeSpec.Generator.Customizations +{ + [AttributeUsage((AttributeTargets.Property | AttributeTargets.Field))] + internal partial class CodeGenMemberAttribute : CodeGenTypeAttribute + { + /// The original name of the member. + public CodeGenMemberAttribute(string originalName) : base(originalName) + { + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs new file mode 100644 index 00000000000..aedb8b359b8 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs @@ -0,0 +1,45 @@ +// + +#nullable disable + +using System; + +namespace Microsoft.TypeSpec.Generator.Customizations +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Struct), AllowMultiple = true, Inherited = true)] + internal partial class CodeGenSerializationAttribute : Attribute + { + /// The property name which these hooks apply to. + public CodeGenSerializationAttribute(string propertyName) + { + PropertyName = propertyName; + } + + /// The property name which these hooks apply to. + /// The serialization name of the property. + public CodeGenSerializationAttribute(string propertyName, string serializationName) + { + PropertyName = propertyName; + SerializationName = serializationName; + } + + /// Gets or sets the property name which these hooks should apply to. + public string PropertyName { get; } + + /// Gets or sets the serialization name of the property. + public string SerializationName { get; set; } + + /// + /// Gets or sets the method name to use when serializing the property value (property name excluded). + /// The signature of the serialization hook method must be or compatible with when invoking: private void SerializeHook(Utf8JsonWriter writer); + /// + public string SerializationValueHook { get; set; } + + /// + /// Gets or sets the method name to use when deserializing the property value from the JSON. + /// private static void DeserializationHook(JsonProperty property, ref TypeOfTheProperty propertyValue); // if the property is required + /// private static void DeserializationHook(JsonProperty property, ref Optional<TypeOfTheProperty> propertyValue); // if the property is optional + /// + public string DeserializationValueHook { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs new file mode 100644 index 00000000000..601ded913ab --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs @@ -0,0 +1,26 @@ +// + +#nullable disable + +using System; + +namespace Microsoft.TypeSpec.Generator.Customizations +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct), AllowMultiple = true)] + internal partial class CodeGenSuppressAttribute : Attribute + { + /// The member to suppress. + /// The types of the parameters of the member. + public CodeGenSuppressAttribute(string member, params Type[] parameters) + { + Member = member; + Parameters = parameters; + } + + /// Gets the Member. + public string Member { get; } + + /// Gets the Parameters. + public Type[] Parameters { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs new file mode 100644 index 00000000000..d7b56bdccdf --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs @@ -0,0 +1,21 @@ +// + +#nullable disable + +using System; + +namespace Microsoft.TypeSpec.Generator.Customizations +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct))] + internal partial class CodeGenTypeAttribute : Attribute + { + /// The original name of the type. + public CodeGenTypeAttribute(string originalName) + { + OriginalName = originalName; + } + + /// Gets the OriginalName. + public string OriginalName { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs new file mode 100644 index 00000000000..ff8a0dc0970 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs @@ -0,0 +1,24 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace Encode._Array +{ + internal partial class ErrorResult : ClientResult + { + private readonly PipelineResponse _response; + private readonly ClientResultException _exception; + + public ErrorResult(PipelineResponse response, ClientResultException exception) : base(default, response) + { + _response = response; + _exception = exception; + } + + /// Gets the Value. + public override T Value => throw _exception; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs new file mode 100644 index 00000000000..a673e55fd85 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs @@ -0,0 +1,265 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text.Json; + +namespace Encode._Array +{ + internal static partial class ModelSerializationExtensions + { + internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W"); + internal static readonly JsonDocumentOptions JsonDocumentOptions = new JsonDocumentOptions + { + MaxDepth = 256 + }; + + public static object GetObject(this JsonElement element) + { + switch (element.ValueKind) + { + case JsonValueKind.String: + return element.GetString(); + case JsonValueKind.Number: + if (element.TryGetInt32(out int intValue)) + { + return intValue; + } + if (element.TryGetInt64(out long longValue)) + { + return longValue; + } + return element.GetDouble(); + case JsonValueKind.True: + return true; + case JsonValueKind.False: + return false; + case JsonValueKind.Undefined: + case JsonValueKind.Null: + return null; + case JsonValueKind.Object: + Dictionary dictionary = new Dictionary(); + foreach (var jsonProperty in element.EnumerateObject()) + { + dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); + } + return dictionary; + case JsonValueKind.Array: + List list = new List(); + foreach (var item in element.EnumerateArray()) + { + list.Add(item.GetObject()); + } + return list.ToArray(); + default: + throw new NotSupportedException($"Not supported value kind {element.ValueKind}"); + } + } + + public static byte[] GetBytesFromBase64(this JsonElement element, string format) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + + return format switch + { + "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()), + "D" => element.GetBytesFromBase64(), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + } + + public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch + { + "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()), + _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format) + }; + + public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format); + + public static char GetChar(this JsonElement element) + { + if (element.ValueKind == JsonValueKind.String) + { + string text = element.GetString(); + if (text == null || text.Length != 1) + { + throw new NotSupportedException($"Cannot convert \"{text}\" to a char"); + } + return text[0]; + } + else + { + throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char"); + } + } + + [Conditional("DEBUG")] + public static void ThrowNonNullablePropertyIsNull(this JsonProperty @property) + { + throw new JsonException($"A property '{@property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build"); + } + + public static string GetRequiredString(this JsonElement element) + { + string value = element.GetString(); + if (value == null) + { + throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'."); + } + return value; + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, char value) + { + writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); + } + + public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + switch (format) + { + case "U": + writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value)); + break; + case "D": + writer.WriteBase64StringValue(value); + break; + default: + throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)); + } + } + + public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + if (format != "U") + { + throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number."); + } + writer.WriteNumberValue(value.ToUnixTimeSeconds()); + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null) + { + switch (value) + { + case null: + writer.WriteNullValue(); + break; + case IJsonModel jsonModel: + jsonModel.Write(writer, options ?? WireOptions); + break; + case byte[] bytes: + writer.WriteBase64StringValue(bytes); + break; + case BinaryData bytes0: + writer.WriteBase64StringValue(bytes0); + break; + case JsonElement json: + json.WriteTo(writer); + break; + case int i: + writer.WriteNumberValue(i); + break; + case decimal d: + writer.WriteNumberValue(d); + break; + case double d0: + if (double.IsNaN(d0)) + { + writer.WriteStringValue("NaN"); + } + else + { + writer.WriteNumberValue(d0); + } + break; + case float f: + writer.WriteNumberValue(f); + break; + case long l: + writer.WriteNumberValue(l); + break; + case string s: + writer.WriteStringValue(s); + break; + case bool b: + writer.WriteBooleanValue(b); + break; + case Guid g: + writer.WriteStringValue(g); + break; + case DateTimeOffset dateTimeOffset: + writer.WriteStringValue(dateTimeOffset, "O"); + break; + case DateTime dateTime: + writer.WriteStringValue(dateTime, "O"); + break; + case IEnumerable> enumerable: + writer.WriteStartObject(); + foreach (var pair in enumerable) + { + writer.WritePropertyName(pair.Key); + writer.WriteObjectValue(pair.Value, options); + } + writer.WriteEndObject(); + break; + case IEnumerable objectEnumerable: + writer.WriteStartArray(); + foreach (var item in objectEnumerable) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + break; + case TimeSpan timeSpan: + writer.WriteStringValue(timeSpan, "P"); + break; + default: + throw new NotSupportedException($"Not supported type {value.GetType()}"); + } + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null) + { + writer.WriteObjectValue(value, options); + } + + public static BinaryData GetUtf8Bytes(this JsonElement element) + { +#if NET9_0_OR_GREATER + return new global::System.BinaryData(global::System.Runtime.InteropServices.JsonMarshal.GetRawUtf8Value(element).ToArray()); +#else + return BinaryData.FromString(element.GetRawText()); +#endif + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs new file mode 100644 index 00000000000..fc734a096a8 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs @@ -0,0 +1,46 @@ +// + +#nullable disable + +namespace Encode._Array +{ + internal enum SerializationFormat + { + /// The default serialization format. + Default = 0, + /// The RFC1123 date time format. + DateTime_RFC1123 = 1, + /// The RFC3339 date time format. + DateTime_RFC3339 = 2, + /// The RFC7231 date time format. + DateTime_RFC7231 = 3, + /// The ISO8601 date time format. + DateTime_ISO8601 = 4, + /// The Unix date time format. + DateTime_Unix = 5, + /// The ISO8601 date format. + Date_ISO8601 = 6, + /// The ISO8601 duration format. + Duration_ISO8601 = 7, + /// The constant duration format. + Duration_Constant = 8, + /// The seconds duration format. + Duration_Seconds = 9, + /// The seconds duration format with float precision. + Duration_Seconds_Float = 10, + /// The seconds duration format with double precision. + Duration_Seconds_Double = 11, + /// The milliseconds duration format. + Duration_Milliseconds = 12, + /// The milliseconds duration format with float precision. + Duration_Milliseconds_Float = 13, + /// The milliseconds duration format with double precision. + Duration_Milliseconds_Double = 14, + /// The ISO8601 time format. + Time_ISO8601 = 15, + /// The Base64Url bytes format. + Bytes_Base64Url = 16, + /// The Base64 bytes format. + Bytes_Base64 = 17 + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs new file mode 100644 index 00000000000..e50bce67d13 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs @@ -0,0 +1,177 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Encode._Array +{ + internal static partial class TypeFormatters + { + private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ"; + public const string DefaultNumberFormat = "G"; + + public static string ToString(bool value) => value ? "true" : "false"; + + public static string ToString(DateTime value, string format) => value.Kind switch + { + DateTimeKind.Utc => ToString((DateTimeOffset)value, format), + _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") + }; + + public static string ToString(DateTimeOffset value, string format) => format switch + { + "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), + "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "R" => value.ToString("r", CultureInfo.InvariantCulture), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(TimeSpan value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToString(value), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(byte[] value, string format) => format switch + { + "U" => ToBase64UrlString(value), + "D" => Convert.ToBase64String(value), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + + public static string ToBase64UrlString(byte[] value) + { + int numWholeOrPartialInputBlocks = checked (value.Length + 2) / 3; + int size = checked (numWholeOrPartialInputBlocks * 4); + char[] output = new char[size]; + + int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0); + + int i = 0; + for (; i < numBase64Chars; i++) + { + char ch = output[i]; + if (ch == '+') + { + output[i] = '-'; + } + else + { + if (ch == '/') + { + output[i] = '_'; + } + else + { + if (ch == '=') + { + break; + } + } + } + } + + return new string(output, 0, i); + } + + public static byte[] FromBase64UrlString(string value) + { + int paddingCharsToAdd = (value.Length % 4) switch + { + 0 => 0, + 2 => 2, + 3 => 1, + _ => throw new InvalidOperationException("Malformed input") + }; + char[] output = new char[(value.Length + paddingCharsToAdd)]; + int i = 0; + for (; i < value.Length; i++) + { + char ch = value[i]; + if (ch == '-') + { + output[i] = '+'; + } + else + { + if (ch == '_') + { + output[i] = '/'; + } + else + { + output[i] = ch; + } + } + } + + for (; i < output.Length; i++) + { + output[i] = '='; + } + + return Convert.FromBase64CharArray(output, 0, output.Length); + } + + public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch + { + "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)), + _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) + }; + + public static TimeSpan ParseTimeSpan(string value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToTimeSpan(value), + _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture) + }; + + public static string ToFormatSpecifier(SerializationFormat format) => format switch + { + SerializationFormat.DateTime_RFC1123 => "R", + SerializationFormat.DateTime_RFC3339 => "O", + SerializationFormat.DateTime_RFC7231 => "R", + SerializationFormat.DateTime_ISO8601 => "O", + SerializationFormat.Date_ISO8601 => "D", + SerializationFormat.DateTime_Unix => "U", + SerializationFormat.Bytes_Base64Url => "U", + SerializationFormat.Bytes_Base64 => "D", + SerializationFormat.Duration_ISO8601 => "P", + SerializationFormat.Duration_Constant => "c", + SerializationFormat.Duration_Seconds => "%s", + SerializationFormat.Duration_Seconds_Float => "s\\.FFF", + SerializationFormat.Duration_Seconds_Double => "s\\.FFFFFF", + SerializationFormat.Time_ISO8601 => "T", + _ => null + }; + + public static string ConvertToString(object value, SerializationFormat format = SerializationFormat.Default) + { + string formatSpecifier = ToFormatSpecifier(format); + + return 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 formatSpecifier != null => ToString(b0, formatSpecifier), + IEnumerable s0 => string.Join(",", s0), + DateTimeOffset dateTime when formatSpecifier != null => ToString(dateTime, formatSpecifier), + TimeSpan timeSpan when format == SerializationFormat.Duration_Seconds => Convert.ToInt32(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture), + TimeSpan timeSpan0 when format == SerializationFormat.Duration_Seconds_Float || format == SerializationFormat.Duration_Seconds_Double => timeSpan0.TotalSeconds.ToString(CultureInfo.InvariantCulture), + TimeSpan timeSpan1 when format == SerializationFormat.Duration_Milliseconds => Convert.ToInt32(timeSpan1.TotalMilliseconds).ToString(CultureInfo.InvariantCulture), + TimeSpan timeSpan2 when format == SerializationFormat.Duration_Milliseconds_Float || format == SerializationFormat.Duration_Milliseconds_Double => timeSpan2.TotalMilliseconds.ToString(CultureInfo.InvariantCulture), + TimeSpan timeSpan3 when formatSpecifier != null => ToString(timeSpan3, formatSpecifier), + TimeSpan timeSpan4 => System.Xml.XmlConvert.ToString(timeSpan4), + Guid guid => guid.ToString(), + BinaryData binaryData => ConvertToString(binaryData.ToArray(), format), + _ => value.ToString() + }; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs index c0c7fbd4732..83b43fc67bf 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs @@ -5,34 +5,155 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { + /// The CommaDelimitedArrayProperty. public partial class CommaDelimitedArrayProperty : IJsonModel { - internal CommaDelimitedArrayProperty() => throw null; + /// Initializes a new instance of for deserialization. + internal CommaDelimitedArrayProperty() + { + } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support writing '{format}' format."); + } + writer.WritePropertyName("value"u8); + writer.WriteStringValue(string.Join(",", Value)); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } - CommaDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + CommaDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual CommaDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual CommaDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCommaDelimitedArrayProperty(document.RootElement, options); + } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static CommaDelimitedArrayProperty DeserializeCommaDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList value = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("value"u8)) + { + string stringValue = prop.Value.GetString(); + value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split(',')); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new CommaDelimitedArrayProperty(value, additionalBinaryDataProperties); + } - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - CommaDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); + default: + throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support writing '{options.Format}' format."); + } + } - protected virtual CommaDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + CommaDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + protected virtual CommaDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeCommaDelimitedArrayProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support reading '{options.Format}' format."); + } + } - public static implicit operator BinaryContent(CommaDelimitedArrayProperty commaDelimitedArrayProperty) => throw null; + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static explicit operator CommaDelimitedArrayProperty(ClientResult result) => throw null; + /// The to serialize into . + public static implicit operator BinaryContent(CommaDelimitedArrayProperty commaDelimitedArrayProperty) + { + if (commaDelimitedArrayProperty == null) + { + return null; + } + return BinaryContent.Create(commaDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator CommaDelimitedArrayProperty(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeCommaDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs index 9e62fadd600..26b6300a619 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs @@ -2,14 +2,38 @@ #nullable disable +using System; using System.Collections.Generic; +using System.Linq; namespace Encode._Array { + /// The CommaDelimitedArrayProperty. public partial class CommaDelimitedArrayProperty { - public CommaDelimitedArrayProperty(IEnumerable value) => throw null; + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; - public IList Value => throw null; + /// Initializes a new instance of . + /// + /// is null. + public CommaDelimitedArrayProperty(IEnumerable value) + { + Argument.AssertNotNull(value, nameof(value)); + + Value = value.ToList(); + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal CommaDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) + { + Value = value; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Value. + public IList Value { get; } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs index f3ab669d97b..51c4d54b3a1 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs @@ -6,6 +6,10 @@ namespace Encode._Array { + /// + /// Context class which will be filled in by the System.ClientModel.SourceGeneration. + /// For more information + /// [ModelReaderWriterBuildable(typeof(CommaDelimitedArrayProperty))] [ModelReaderWriterBuildable(typeof(NewlineDelimitedArrayProperty))] [ModelReaderWriterBuildable(typeof(PipeDelimitedArrayProperty))] diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs index cd31ef81498..b53098449f6 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs @@ -5,34 +5,155 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { + /// The NewlineDelimitedArrayProperty. public partial class NewlineDelimitedArrayProperty : IJsonModel { - internal NewlineDelimitedArrayProperty() => throw null; + /// Initializes a new instance of for deserialization. + internal NewlineDelimitedArrayProperty() + { + } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support writing '{format}' format."); + } + writer.WritePropertyName("value"u8); + writer.WriteStringValue(string.Join("\n", Value)); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } - NewlineDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + NewlineDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual NewlineDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual NewlineDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNewlineDelimitedArrayProperty(document.RootElement, options); + } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static NewlineDelimitedArrayProperty DeserializeNewlineDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList value = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("value"u8)) + { + string stringValue = prop.Value.GetString(); + value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split('\n')); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new NewlineDelimitedArrayProperty(value, additionalBinaryDataProperties); + } - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - NewlineDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); + default: + throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support writing '{options.Format}' format."); + } + } - protected virtual NewlineDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + NewlineDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + protected virtual NewlineDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeNewlineDelimitedArrayProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support reading '{options.Format}' format."); + } + } - public static implicit operator BinaryContent(NewlineDelimitedArrayProperty newlineDelimitedArrayProperty) => throw null; + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static explicit operator NewlineDelimitedArrayProperty(ClientResult result) => throw null; + /// The to serialize into . + public static implicit operator BinaryContent(NewlineDelimitedArrayProperty newlineDelimitedArrayProperty) + { + if (newlineDelimitedArrayProperty == null) + { + return null; + } + return BinaryContent.Create(newlineDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator NewlineDelimitedArrayProperty(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeNewlineDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs index 1680d3dcc06..677c73e072d 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs @@ -2,14 +2,38 @@ #nullable disable +using System; using System.Collections.Generic; +using System.Linq; namespace Encode._Array { + /// The NewlineDelimitedArrayProperty. public partial class NewlineDelimitedArrayProperty { - public NewlineDelimitedArrayProperty(IEnumerable value) => throw null; + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; - public IList Value => throw null; + /// Initializes a new instance of . + /// + /// is null. + public NewlineDelimitedArrayProperty(IEnumerable value) + { + Argument.AssertNotNull(value, nameof(value)); + + Value = value.ToList(); + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal NewlineDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) + { + Value = value; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Value. + public IList Value { get; } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs index 77fb59cc6da..2c34cf35208 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs @@ -5,34 +5,155 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { + /// The PipeDelimitedArrayProperty. public partial class PipeDelimitedArrayProperty : IJsonModel { - internal PipeDelimitedArrayProperty() => throw null; + /// Initializes a new instance of for deserialization. + internal PipeDelimitedArrayProperty() + { + } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support writing '{format}' format."); + } + writer.WritePropertyName("value"u8); + writer.WriteStringValue(string.Join("|", Value)); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } - PipeDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + PipeDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual PipeDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual PipeDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePipeDelimitedArrayProperty(document.RootElement, options); + } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static PipeDelimitedArrayProperty DeserializePipeDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList value = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("value"u8)) + { + string stringValue = prop.Value.GetString(); + value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split('|')); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new PipeDelimitedArrayProperty(value, additionalBinaryDataProperties); + } - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - PipeDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); + default: + throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support writing '{options.Format}' format."); + } + } - protected virtual PipeDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + PipeDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + protected virtual PipeDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializePipeDelimitedArrayProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support reading '{options.Format}' format."); + } + } - public static implicit operator BinaryContent(PipeDelimitedArrayProperty pipeDelimitedArrayProperty) => throw null; + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static explicit operator PipeDelimitedArrayProperty(ClientResult result) => throw null; + /// The to serialize into . + public static implicit operator BinaryContent(PipeDelimitedArrayProperty pipeDelimitedArrayProperty) + { + if (pipeDelimitedArrayProperty == null) + { + return null; + } + return BinaryContent.Create(pipeDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator PipeDelimitedArrayProperty(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializePipeDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs index a8267bbaf53..fcd20bf64c6 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs @@ -2,14 +2,38 @@ #nullable disable +using System; using System.Collections.Generic; +using System.Linq; namespace Encode._Array { + /// The PipeDelimitedArrayProperty. public partial class PipeDelimitedArrayProperty { - public PipeDelimitedArrayProperty(IEnumerable value) => throw null; + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; - public IList Value => throw null; + /// Initializes a new instance of . + /// + /// is null. + public PipeDelimitedArrayProperty(IEnumerable value) + { + Argument.AssertNotNull(value, nameof(value)); + + Value = value.ToList(); + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal PipeDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) + { + Value = value; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Value. + public IList Value { get; } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs index d37d4f47a96..dc4cd5a8ec5 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs @@ -5,34 +5,155 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { + /// The SpaceDelimitedArrayProperty. public partial class SpaceDelimitedArrayProperty : IJsonModel { - internal SpaceDelimitedArrayProperty() => throw null; + /// Initializes a new instance of for deserialization. + internal SpaceDelimitedArrayProperty() + { + } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support writing '{format}' format."); + } + writer.WritePropertyName("value"u8); + writer.WriteStringValue(string.Join(" ", Value)); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } - SpaceDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + SpaceDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual SpaceDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual SpaceDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSpaceDelimitedArrayProperty(document.RootElement, options); + } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static SpaceDelimitedArrayProperty DeserializeSpaceDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList value = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("value"u8)) + { + string stringValue = prop.Value.GetString(); + value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split(' ')); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new SpaceDelimitedArrayProperty(value, additionalBinaryDataProperties); + } - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - SpaceDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); + default: + throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support writing '{options.Format}' format."); + } + } - protected virtual SpaceDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + SpaceDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; + /// The data to parse. + /// The client options for reading and writing models. + protected virtual SpaceDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeSpaceDelimitedArrayProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support reading '{options.Format}' format."); + } + } - public static implicit operator BinaryContent(SpaceDelimitedArrayProperty spaceDelimitedArrayProperty) => throw null; + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static explicit operator SpaceDelimitedArrayProperty(ClientResult result) => throw null; + /// The to serialize into . + public static implicit operator BinaryContent(SpaceDelimitedArrayProperty spaceDelimitedArrayProperty) + { + if (spaceDelimitedArrayProperty == null) + { + return null; + } + return BinaryContent.Create(spaceDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator SpaceDelimitedArrayProperty(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeSpaceDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs index e93bddfb965..c5dff570ab2 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs @@ -2,14 +2,38 @@ #nullable disable +using System; using System.Collections.Generic; +using System.Linq; namespace Encode._Array { + /// The SpaceDelimitedArrayProperty. public partial class SpaceDelimitedArrayProperty { - public SpaceDelimitedArrayProperty(IEnumerable value) => throw null; + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; - public IList Value => throw null; + /// Initializes a new instance of . + /// + /// is null. + public SpaceDelimitedArrayProperty(IEnumerable value) + { + Argument.AssertNotNull(value, nameof(value)); + + Value = value.ToList(); + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal SpaceDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) + { + Value = value; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Value. + public IList Value { get; } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs new file mode 100644 index 00000000000..59896be6f55 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs @@ -0,0 +1,74 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; +using Encode._Array; + +namespace Encode._Array._Property +{ + /// + public partial class Property + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateCommaDelimitedRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/encode/array/property/comma-delimited", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateSpaceDelimitedRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/encode/array/property/space-delimited", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreatePipeDelimitedRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/encode/array/property/pipe-delimited", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateNewlineDelimitedRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/encode/array/property/newline-delimited", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs index e50400b6ee6..6c79d0514e1 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs @@ -2,6 +2,7 @@ #nullable disable +using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Threading; @@ -10,42 +11,298 @@ namespace Encode._Array._Property { + /// The Property sub-client. public partial class Property { - protected Property() => throw null; + private readonly Uri _endpoint; - public ClientPipeline Pipeline => throw null; + /// Initializes a new instance of Property for mocking. + protected Property() + { + } - public virtual ClientResult CommaDelimited(BinaryContent content, RequestOptions options = null) => throw null; + /// Initializes a new instance of Property. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal Property(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } - public virtual Task CommaDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } - public virtual ClientResult CommaDelimited(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + /// + /// [Protocol Method] CommaDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 ClientResult CommaDelimited(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); - public virtual Task> CommaDelimitedAsync(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + using PipelineMessage message = CreateCommaDelimitedRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } - public virtual ClientResult SpaceDelimited(BinaryContent content, RequestOptions options = null) => throw null; + /// + /// [Protocol Method] CommaDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 CommaDelimitedAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); - public virtual Task SpaceDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateCommaDelimitedRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } - public virtual ClientResult SpaceDelimited(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + /// CommaDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult CommaDelimited(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); - public virtual Task> SpaceDelimitedAsync(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + ClientResult result = CommaDelimited(body, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((CommaDelimitedArrayProperty)result, result.GetRawResponse()); + } - public virtual ClientResult PipeDelimited(BinaryContent content, RequestOptions options = null) => throw null; + /// CommaDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> CommaDelimitedAsync(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); - public virtual Task PipeDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; + ClientResult result = await CommaDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((CommaDelimitedArrayProperty)result, result.GetRawResponse()); + } - public virtual ClientResult PipeDelimited(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + /// + /// [Protocol Method] SpaceDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 ClientResult SpaceDelimited(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); - public virtual Task> PipeDelimitedAsync(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + using PipelineMessage message = CreateSpaceDelimitedRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } - public virtual ClientResult NewlineDelimited(BinaryContent content, RequestOptions options = null) => throw null; + /// + /// [Protocol Method] SpaceDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 SpaceDelimitedAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); - public virtual Task NewlineDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; + using PipelineMessage message = CreateSpaceDelimitedRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } - public virtual ClientResult NewlineDelimited(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + /// SpaceDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult SpaceDelimited(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); - public virtual Task> NewlineDelimitedAsync(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; + ClientResult result = SpaceDelimited(body, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((SpaceDelimitedArrayProperty)result, result.GetRawResponse()); + } + + /// SpaceDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> SpaceDelimitedAsync(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + ClientResult result = await SpaceDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((SpaceDelimitedArrayProperty)result, result.GetRawResponse()); + } + + /// + /// [Protocol Method] PipeDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 ClientResult PipeDelimited(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreatePipeDelimitedRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] PipeDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 PipeDelimitedAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreatePipeDelimitedRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// PipeDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult PipeDelimited(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + ClientResult result = PipeDelimited(body, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((PipeDelimitedArrayProperty)result, result.GetRawResponse()); + } + + /// PipeDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> PipeDelimitedAsync(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + ClientResult result = await PipeDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((PipeDelimitedArrayProperty)result, result.GetRawResponse()); + } + + /// + /// [Protocol Method] NewlineDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 ClientResult NewlineDelimited(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateNewlineDelimitedRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] NewlineDelimited + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, 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 NewlineDelimitedAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateNewlineDelimitedRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// NewlineDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult NewlineDelimited(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + ClientResult result = NewlineDelimited(body, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((NewlineDelimitedArrayProperty)result, result.GetRawResponse()); + } + + /// NewlineDelimited. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> NewlineDelimitedAsync(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(body, nameof(body)); + + ClientResult result = await NewlineDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((NewlineDelimitedArrayProperty)result, result.GetRawResponse()); + } } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/tspCodeModel.json index 7820bc1b0d2..8e600a1fa50 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/tspCodeModel.json @@ -172,7 +172,8 @@ "name": "value" } }, - "isHttpMetadata": false + "isHttpMetadata": false, + "encode": "commaDelimited" } ] }, @@ -204,7 +205,8 @@ "name": "value" } }, - "isHttpMetadata": false + "isHttpMetadata": false, + "encode": "spaceDelimited" } ] }, @@ -236,7 +238,8 @@ "name": "value" } }, - "isHttpMetadata": false + "isHttpMetadata": false, + "encode": "pipeDelimited" } ] }, @@ -268,7 +271,8 @@ "name": "value" } }, - "isHttpMetadata": false + "isHttpMetadata": false, + "encode": "newlineDelimited" } ] } From fbbfaf5b2ecff127326dd7eee45f129e2cbdddd4 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 22 Jan 2026 13:55:31 -0800 Subject: [PATCH 3/8] geenrate script --- .../src/Generated/ArrayClient.RestClient.cs | 11 - .../encode/array/src/Generated/ArrayClient.cs | 33 +- .../array/src/Generated/ArrayClientOptions.cs | 1 - .../src/Generated/EncodeArrayModelFactory.cs | 42 +-- .../array/src/Generated/Internal/Argument.cs | 71 ----- .../Internal/CancellationTokenExtensions.cs | 14 - .../Internal/ChangeTrackingDictionary.cs | 186 ----------- .../Generated/Internal/ChangeTrackingList.cs | 165 ---------- .../Internal/ClientPipelineExtensions.cs | 67 ---- .../Generated/Internal/ClientUriBuilder.cs | 137 -------- .../Internal/CodeGenMemberAttribute.cs | 17 - .../Internal/CodeGenSerializationAttribute.cs | 45 --- .../Internal/CodeGenSuppressAttribute.cs | 26 -- .../Internal/CodeGenTypeAttribute.cs | 21 -- .../src/Generated/Internal/ErrorResult.cs | 24 -- .../Internal/ModelSerializationExtensions.cs | 265 ---------------- .../Generated/Internal/SerializationFormat.cs | 46 --- .../src/Generated/Internal/TypeFormatters.cs | 177 ----------- ...mmaDelimitedArrayProperty.Serialization.cs | 145 +-------- .../Models/CommaDelimitedArrayProperty.cs | 28 +- .../Generated/Models/Encode_ArrayContext.cs | 4 - ...ineDelimitedArrayProperty.Serialization.cs | 145 +-------- .../Models/NewlineDelimitedArrayProperty.cs | 28 +- ...ipeDelimitedArrayProperty.Serialization.cs | 145 +-------- .../Models/PipeDelimitedArrayProperty.cs | 28 +- ...aceDelimitedArrayProperty.Serialization.cs | 145 +-------- .../Models/SpaceDelimitedArrayProperty.cs | 28 +- .../src/Generated/Property.RestClient.cs | 74 ----- .../encode/array/src/Generated/Property.cs | 293 ++---------------- 29 files changed, 82 insertions(+), 2329 deletions(-) delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs delete mode 100644 packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs deleted file mode 100644 index d94692a69fe..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.RestClient.cs +++ /dev/null @@ -1,11 +0,0 @@ -// - -#nullable disable - -namespace Encode._Array -{ - /// - public partial class ArrayClient - { - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs index b175ca06967..55ae5b366f0 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClient.cs @@ -4,43 +4,18 @@ using System; using System.ClientModel.Primitives; -using System.Threading; using Encode._Array._Property; namespace Encode._Array { - /// Test for encode decorator on array. public partial class ArrayClient { - private readonly Uri _endpoint; - private Property _cachedProperty; + public ArrayClient() : this(new Uri("http://localhost:3000"), new ArrayClientOptions()) => throw null; - /// Initializes a new instance of ArrayClient. - public ArrayClient() : this(new Uri("http://localhost:3000"), new ArrayClientOptions()) - { - } + public ArrayClient(Uri endpoint, ArrayClientOptions options) => throw null; - /// Initializes a new instance of ArrayClient. - /// Service endpoint. - /// The options for configuring the client. - /// is null. - public ArrayClient(Uri endpoint, ArrayClientOptions options) - { - Argument.AssertNotNull(endpoint, nameof(endpoint)); + public ClientPipeline Pipeline => throw null; - options ??= new ArrayClientOptions(); - - _endpoint = endpoint; - Pipeline = ClientPipeline.Create(options, Array.Empty(), new PipelinePolicy[] { new UserAgentPolicy(typeof(ArrayClient).Assembly) }, Array.Empty()); - } - - /// The HTTP pipeline for sending and receiving REST requests and responses. - public ClientPipeline Pipeline { get; } - - /// Initializes a new instance of Property. - public virtual Property GetPropertyClient() - { - return Volatile.Read(ref _cachedProperty) ?? Interlocked.CompareExchange(ref _cachedProperty, new Property(Pipeline, _endpoint), null) ?? _cachedProperty; - } + public virtual Property GetPropertyClient() => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs index abbd7e7d76a..392d2e67a55 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/ArrayClientOptions.cs @@ -6,7 +6,6 @@ namespace Encode._Array { - /// Client options for . public partial class ArrayClientOptions : ClientPipelineOptions { } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs index a6207ca2740..f1b065009ce 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/EncodeArrayModelFactory.cs @@ -3,51 +3,17 @@ #nullable disable using System.Collections.Generic; -using System.Linq; namespace Encode._Array { - /// A factory class for creating instances of the models for mocking. public static partial class EncodeArrayModelFactory { - /// The CommaDelimitedArrayProperty. - /// - /// A new instance for mocking. - public static CommaDelimitedArrayProperty CommaDelimitedArrayProperty(IEnumerable value = default) - { - value ??= new ChangeTrackingList(); + public static CommaDelimitedArrayProperty CommaDelimitedArrayProperty(IEnumerable value = default) => throw null; - return new CommaDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); - } + public static SpaceDelimitedArrayProperty SpaceDelimitedArrayProperty(IEnumerable value = default) => throw null; - /// The SpaceDelimitedArrayProperty. - /// - /// A new instance for mocking. - public static SpaceDelimitedArrayProperty SpaceDelimitedArrayProperty(IEnumerable value = default) - { - value ??= new ChangeTrackingList(); + public static PipeDelimitedArrayProperty PipeDelimitedArrayProperty(IEnumerable value = default) => throw null; - return new SpaceDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); - } - - /// The PipeDelimitedArrayProperty. - /// - /// A new instance for mocking. - public static PipeDelimitedArrayProperty PipeDelimitedArrayProperty(IEnumerable value = default) - { - value ??= new ChangeTrackingList(); - - return new PipeDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); - } - - /// The NewlineDelimitedArrayProperty. - /// - /// A new instance for mocking. - public static NewlineDelimitedArrayProperty NewlineDelimitedArrayProperty(IEnumerable value = default) - { - value ??= new ChangeTrackingList(); - - return new NewlineDelimitedArrayProperty(value.ToList(), additionalBinaryDataProperties: null); - } + public static NewlineDelimitedArrayProperty NewlineDelimitedArrayProperty(IEnumerable value = default) => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs deleted file mode 100644 index 538eb79fc39..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/Argument.cs +++ /dev/null @@ -1,71 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Encode._Array -{ - internal static partial class Argument - { - /// The value. - /// The name. - public static void AssertNotNull(T value, string name) - { - if (value is null) - { - throw new ArgumentNullException(name); - } - } - - /// The value. - /// The name. - public static void AssertNotNull(T? value, string name) - where T : struct - { - if (!value.HasValue) - { - throw new ArgumentNullException(name); - } - } - - /// The value. - /// The 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); - } - } - - /// The value. - /// The 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); - } - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs deleted file mode 100644 index 5ff23ae7999..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CancellationTokenExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// - -#nullable disable - -using System.ClientModel.Primitives; -using System.Threading; - -namespace Encode._Array -{ - internal static partial class CancellationTokenExtensions - { - public static RequestOptions ToRequestOptions(this CancellationToken cancellationToken) => cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null; - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs deleted file mode 100644 index b406a43171d..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingDictionary.cs +++ /dev/null @@ -1,186 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Encode._Array -{ - internal partial class ChangeTrackingDictionary : IDictionary, IReadOnlyDictionary - where TKey : notnull - { - private IDictionary _innerDictionary; - - public ChangeTrackingDictionary() - { - } - - /// The inner dictionary. - public ChangeTrackingDictionary(IDictionary dictionary) - { - if (dictionary == null) - { - return; - } - _innerDictionary = new Dictionary(dictionary); - } - - /// The inner dictionary. - public ChangeTrackingDictionary(IReadOnlyDictionary dictionary) - { - if (dictionary == null) - { - return; - } - _innerDictionary = new Dictionary(); - foreach (var pair in dictionary) - { - _innerDictionary.Add(pair); - } - } - - /// Gets the IsUndefined. - public bool IsUndefined => _innerDictionary == null; - - /// Gets the Count. - public int Count => IsUndefined ? 0 : EnsureDictionary().Count; - - /// Gets the IsReadOnly. - public bool IsReadOnly => IsUndefined ? false : EnsureDictionary().IsReadOnly; - - /// Gets the Keys. - public ICollection Keys => IsUndefined ? Array.Empty() : EnsureDictionary().Keys; - - /// Gets the Values. - public ICollection Values => IsUndefined ? Array.Empty() : EnsureDictionary().Values; - - /// Gets or sets the value associated with the specified key. - public TValue this[TKey key] - { - get - { - if (IsUndefined) - { - throw new KeyNotFoundException(nameof(key)); - } - return EnsureDictionary()[key]; - } - set - { - EnsureDictionary()[key] = value; - } - } - - /// Gets the Keys. - IEnumerable IReadOnlyDictionary.Keys => Keys; - - /// Gets the Values. - IEnumerable IReadOnlyDictionary.Values => Values; - - public IEnumerator> GetEnumerator() - { - if (IsUndefined) - { - IEnumerator> enumerateEmpty() - { - yield break; - } - return enumerateEmpty(); - } - return EnsureDictionary().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// The item to add. - public void Add(KeyValuePair item) - { - EnsureDictionary().Add(item); - } - - public void Clear() - { - EnsureDictionary().Clear(); - } - - /// The item to search for. - public bool Contains(KeyValuePair item) - { - if (IsUndefined) - { - return false; - } - return EnsureDictionary().Contains(item); - } - - /// The array to copy. - /// The index. - public void CopyTo(KeyValuePair[] array, int index) - { - if (IsUndefined) - { - return; - } - EnsureDictionary().CopyTo(array, index); - } - - /// The item to remove. - public bool Remove(KeyValuePair item) - { - if (IsUndefined) - { - return false; - } - return EnsureDictionary().Remove(item); - } - - /// The key. - /// The value to add. - public void Add(TKey key, TValue value) - { - EnsureDictionary().Add(key, value); - } - - /// The key to search for. - public bool ContainsKey(TKey key) - { - if (IsUndefined) - { - return false; - } - return EnsureDictionary().ContainsKey(key); - } - - /// The key. - public bool Remove(TKey key) - { - if (IsUndefined) - { - return false; - } - return EnsureDictionary().Remove(key); - } - - /// The key to search for. - /// The value. - 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/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs deleted file mode 100644 index b46ae0c8c5b..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ChangeTrackingList.cs +++ /dev/null @@ -1,165 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace Encode._Array -{ - internal partial class ChangeTrackingList : IList, IReadOnlyList - { - private IList _innerList; - - public ChangeTrackingList() - { - } - - /// The inner list. - public ChangeTrackingList(IList innerList) - { - if (innerList != null) - { - _innerList = innerList; - } - } - - /// The inner list. - public ChangeTrackingList(IReadOnlyList innerList) - { - if (innerList != null) - { - _innerList = innerList.ToList(); - } - } - - /// Gets the IsUndefined. - public bool IsUndefined => _innerList == null; - - /// Gets the Count. - public int Count => IsUndefined ? 0 : EnsureList().Count; - - /// Gets the IsReadOnly. - public bool IsReadOnly => IsUndefined ? false : EnsureList().IsReadOnly; - - /// Gets or sets the value associated with the specified key. - 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(); - } - - /// The item to add. - public void Add(T item) - { - EnsureList().Add(item); - } - - public void Clear() - { - EnsureList().Clear(); - } - - /// The item. - public bool Contains(T item) - { - if (IsUndefined) - { - return false; - } - return EnsureList().Contains(item); - } - - /// The array to copy to. - /// The array index. - public void CopyTo(T[] array, int arrayIndex) - { - if (IsUndefined) - { - return; - } - EnsureList().CopyTo(array, arrayIndex); - } - - /// The item. - public bool Remove(T item) - { - if (IsUndefined) - { - return false; - } - return EnsureList().Remove(item); - } - - /// The item. - public int IndexOf(T item) - { - if (IsUndefined) - { - return -1; - } - return EnsureList().IndexOf(item); - } - - /// The inner list. - /// The item. - public void Insert(int index, T item) - { - EnsureList().Insert(index, item); - } - - /// The inner list. - 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/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs deleted file mode 100644 index 0b31f807b50..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientPipelineExtensions.cs +++ /dev/null @@ -1,67 +0,0 @@ -// - -#nullable disable - -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Threading.Tasks; - -namespace Encode._Array -{ - internal static partial class ClientPipelineExtensions - { - public static async ValueTask ProcessMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) - { - await pipeline.SendAsync(message).ConfigureAwait(false); - - if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) - { - throw await ClientResultException.CreateAsync(message.Response).ConfigureAwait(false); - } - - PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); - return response; - } - - public static PipelineResponse ProcessMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) - { - pipeline.Send(message); - - if (message.Response.IsError && (options?.ErrorOptions & ClientErrorBehaviors.NoThrow) != ClientErrorBehaviors.NoThrow) - { - throw new ClientResultException(message.Response); - } - - PipelineResponse response = message.BufferResponse ? message.Response : message.ExtractResponse(); - return response; - } - - public static async ValueTask> ProcessHeadAsBoolMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) - { - PipelineResponse response = await pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false); - switch (response.Status) - { - case >= 200 and < 300: - return ClientResult.FromValue(true, response); - case >= 400 and < 500: - return ClientResult.FromValue(false, response); - default: - return new ErrorResult(response, new ClientResultException(response)); - } - } - - public static ClientResult ProcessHeadAsBoolMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) - { - PipelineResponse response = pipeline.ProcessMessage(message, options); - switch (response.Status) - { - case >= 200 and < 300: - return ClientResult.FromValue(true, response); - case >= 400 and < 500: - return ClientResult.FromValue(false, response); - default: - return new ErrorResult(response, new ClientResultException(response)); - } - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs deleted file mode 100644 index b8f39fce3d1..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ClientUriBuilder.cs +++ /dev/null @@ -1,137 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Encode._Array -{ - internal partial class ClientUriBuilder - { - private UriBuilder _uriBuilder; - private StringBuilder _pathAndQuery; - private int _pathLength; - - public ClientUriBuilder() - { - } - - private UriBuilder UriBuilder => _uriBuilder ??= new UriBuilder(); - - private StringBuilder PathAndQuery => _pathAndQuery ??= new StringBuilder(); - - public void Reset(Uri uri) - { - _uriBuilder = new UriBuilder(uri); - PathAndQuery.Clear(); - PathAndQuery.Append(UriBuilder.Path); - _pathLength = PathAndQuery.Length; - PathAndQuery.Append(UriBuilder.Query); - } - - public void AppendPath(string value, bool escape) - { - if (escape) - { - value = Uri.EscapeDataString(value); - } - if (_pathLength > 0 && PathAndQuery[_pathLength - 1] == '/' && value[0] == '/') - { - PathAndQuery.Remove(_pathLength - 1, 1); - _pathLength = _pathLength - 1; - } - PathAndQuery.Insert(_pathLength, value); - _pathLength = _pathLength + value.Length; - } - - public void AppendPath(bool value, bool escape = false) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPath(float value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPath(double value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPath(int value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPath(byte[] value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); - - public void AppendPath(DateTimeOffset value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); - - public void AppendPath(TimeSpan value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value, format), escape); - - public void AppendPath(Guid value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPath(long value, bool escape = true) => AppendPath(TypeFormatters.ConvertToString(value), escape); - - public void AppendPathDelimited(IEnumerable value, string delimiter, SerializationFormat format = SerializationFormat.Default, bool escape = true) - { - delimiter ??= ","; - IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); - AppendPath(string.Join(delimiter, stringValues), escape); - } - - public void AppendQuery(string name, string value, bool escape) - { - if (PathAndQuery.Length == _pathLength) - { - PathAndQuery.Append('?'); - } - if (PathAndQuery.Length > _pathLength && PathAndQuery[PathAndQuery.Length - 1] != '?') - { - PathAndQuery.Append('&'); - } - if (escape) - { - value = Uri.EscapeDataString(value); - } - PathAndQuery.Append(name); - PathAndQuery.Append('='); - PathAndQuery.Append(value); - } - - public void AppendQuery(string name, bool value, bool escape = false) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, float value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, DateTimeOffset value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); - - public void AppendQuery(string name, TimeSpan value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); - - public void AppendQuery(string name, double value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, decimal value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, int value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, long value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, TimeSpan value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQuery(string name, byte[] value, SerializationFormat format = SerializationFormat.Default, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value, format), escape); - - public void AppendQuery(string name, Guid value, bool escape = true) => AppendQuery(name, TypeFormatters.ConvertToString(value), escape); - - public void AppendQueryDelimited(string name, IEnumerable value, string delimiter, SerializationFormat format = SerializationFormat.Default, bool escape = true) - { - delimiter ??= ","; - IEnumerable stringValues = value.Select(v => TypeFormatters.ConvertToString(v, format)); - AppendQuery(name, string.Join(delimiter, stringValues), escape); - } - - public Uri ToUri() - { - UriBuilder.Path = PathAndQuery.ToString(0, _pathLength); - if (PathAndQuery.Length > _pathLength) - { - UriBuilder.Query = PathAndQuery.ToString(_pathLength + 1, PathAndQuery.Length - _pathLength - 1); - } - if (PathAndQuery.Length == _pathLength) - { - UriBuilder.Query = ""; - } - return UriBuilder.Uri; - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs deleted file mode 100644 index 044dfe314c5..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenMemberAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// - -#nullable disable - -using System; - -namespace Microsoft.TypeSpec.Generator.Customizations -{ - [AttributeUsage((AttributeTargets.Property | AttributeTargets.Field))] - internal partial class CodeGenMemberAttribute : CodeGenTypeAttribute - { - /// The original name of the member. - public CodeGenMemberAttribute(string originalName) : base(originalName) - { - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs deleted file mode 100644 index aedb8b359b8..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSerializationAttribute.cs +++ /dev/null @@ -1,45 +0,0 @@ -// - -#nullable disable - -using System; - -namespace Microsoft.TypeSpec.Generator.Customizations -{ - [AttributeUsage((AttributeTargets.Class | AttributeTargets.Struct), AllowMultiple = true, Inherited = true)] - internal partial class CodeGenSerializationAttribute : Attribute - { - /// The property name which these hooks apply to. - public CodeGenSerializationAttribute(string propertyName) - { - PropertyName = propertyName; - } - - /// The property name which these hooks apply to. - /// The serialization name of the property. - public CodeGenSerializationAttribute(string propertyName, string serializationName) - { - PropertyName = propertyName; - SerializationName = serializationName; - } - - /// Gets or sets the property name which these hooks should apply to. - public string PropertyName { get; } - - /// Gets or sets the serialization name of the property. - public string SerializationName { get; set; } - - /// - /// Gets or sets the method name to use when serializing the property value (property name excluded). - /// The signature of the serialization hook method must be or compatible with when invoking: private void SerializeHook(Utf8JsonWriter writer); - /// - public string SerializationValueHook { get; set; } - - /// - /// Gets or sets the method name to use when deserializing the property value from the JSON. - /// private static void DeserializationHook(JsonProperty property, ref TypeOfTheProperty propertyValue); // if the property is required - /// private static void DeserializationHook(JsonProperty property, ref Optional<TypeOfTheProperty> propertyValue); // if the property is optional - /// - public string DeserializationValueHook { get; set; } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs deleted file mode 100644 index 601ded913ab..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenSuppressAttribute.cs +++ /dev/null @@ -1,26 +0,0 @@ -// - -#nullable disable - -using System; - -namespace Microsoft.TypeSpec.Generator.Customizations -{ - [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct), AllowMultiple = true)] - internal partial class CodeGenSuppressAttribute : Attribute - { - /// The member to suppress. - /// The types of the parameters of the member. - public CodeGenSuppressAttribute(string member, params Type[] parameters) - { - Member = member; - Parameters = parameters; - } - - /// Gets the Member. - public string Member { get; } - - /// Gets the Parameters. - public Type[] Parameters { get; } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs deleted file mode 100644 index d7b56bdccdf..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/CodeGenTypeAttribute.cs +++ /dev/null @@ -1,21 +0,0 @@ -// - -#nullable disable - -using System; - -namespace Microsoft.TypeSpec.Generator.Customizations -{ - [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct))] - internal partial class CodeGenTypeAttribute : Attribute - { - /// The original name of the type. - public CodeGenTypeAttribute(string originalName) - { - OriginalName = originalName; - } - - /// Gets the OriginalName. - public string OriginalName { get; } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs deleted file mode 100644 index ff8a0dc0970..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ErrorResult.cs +++ /dev/null @@ -1,24 +0,0 @@ -// - -#nullable disable - -using System.ClientModel; -using System.ClientModel.Primitives; - -namespace Encode._Array -{ - internal partial class ErrorResult : ClientResult - { - private readonly PipelineResponse _response; - private readonly ClientResultException _exception; - - public ErrorResult(PipelineResponse response, ClientResultException exception) : base(default, response) - { - _response = response; - _exception = exception; - } - - /// Gets the Value. - public override T Value => throw _exception; - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs deleted file mode 100644 index a673e55fd85..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/ModelSerializationExtensions.cs +++ /dev/null @@ -1,265 +0,0 @@ -// - -#nullable disable - -using System; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text.Json; - -namespace Encode._Array -{ - internal static partial class ModelSerializationExtensions - { - internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W"); - internal static readonly JsonDocumentOptions JsonDocumentOptions = new JsonDocumentOptions - { - MaxDepth = 256 - }; - - public static object GetObject(this JsonElement element) - { - switch (element.ValueKind) - { - case JsonValueKind.String: - return element.GetString(); - case JsonValueKind.Number: - if (element.TryGetInt32(out int intValue)) - { - return intValue; - } - if (element.TryGetInt64(out long longValue)) - { - return longValue; - } - return element.GetDouble(); - case JsonValueKind.True: - return true; - case JsonValueKind.False: - return false; - case JsonValueKind.Undefined: - case JsonValueKind.Null: - return null; - case JsonValueKind.Object: - Dictionary dictionary = new Dictionary(); - foreach (var jsonProperty in element.EnumerateObject()) - { - dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); - } - return dictionary; - case JsonValueKind.Array: - List list = new List(); - foreach (var item in element.EnumerateArray()) - { - list.Add(item.GetObject()); - } - return list.ToArray(); - default: - throw new NotSupportedException($"Not supported value kind {element.ValueKind}"); - } - } - - public static byte[] GetBytesFromBase64(this JsonElement element, string format) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - - return format switch - { - "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()), - "D" => element.GetBytesFromBase64(), - _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) - }; - } - - public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch - { - "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()), - _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format) - }; - - public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format); - - public static char GetChar(this JsonElement element) - { - if (element.ValueKind == JsonValueKind.String) - { - string text = element.GetString(); - if (text == null || text.Length != 1) - { - throw new NotSupportedException($"Cannot convert \"{text}\" to a char"); - } - return text[0]; - } - else - { - throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char"); - } - } - - [Conditional("DEBUG")] - public static void ThrowNonNullablePropertyIsNull(this JsonProperty @property) - { - throw new JsonException($"A property '{@property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build"); - } - - public static string GetRequiredString(this JsonElement element) - { - string value = element.GetString(); - if (value == null) - { - throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'."); - } - return value; - } - - public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) - { - writer.WriteStringValue(TypeFormatters.ToString(value, format)); - } - - public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format) - { - writer.WriteStringValue(TypeFormatters.ToString(value, format)); - } - - public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format) - { - writer.WriteStringValue(TypeFormatters.ToString(value, format)); - } - - public static void WriteStringValue(this Utf8JsonWriter writer, char value) - { - writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); - } - - public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format) - { - if (value == null) - { - writer.WriteNullValue(); - return; - } - switch (format) - { - case "U": - writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value)); - break; - case "D": - writer.WriteBase64StringValue(value); - break; - default: - throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)); - } - } - - public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) - { - if (format != "U") - { - throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number."); - } - writer.WriteNumberValue(value.ToUnixTimeSeconds()); - } - - public static void WriteObjectValue(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null) - { - switch (value) - { - case null: - writer.WriteNullValue(); - break; - case IJsonModel jsonModel: - jsonModel.Write(writer, options ?? WireOptions); - break; - case byte[] bytes: - writer.WriteBase64StringValue(bytes); - break; - case BinaryData bytes0: - writer.WriteBase64StringValue(bytes0); - break; - case JsonElement json: - json.WriteTo(writer); - break; - case int i: - writer.WriteNumberValue(i); - break; - case decimal d: - writer.WriteNumberValue(d); - break; - case double d0: - if (double.IsNaN(d0)) - { - writer.WriteStringValue("NaN"); - } - else - { - writer.WriteNumberValue(d0); - } - break; - case float f: - writer.WriteNumberValue(f); - break; - case long l: - writer.WriteNumberValue(l); - break; - case string s: - writer.WriteStringValue(s); - break; - case bool b: - writer.WriteBooleanValue(b); - break; - case Guid g: - writer.WriteStringValue(g); - break; - case DateTimeOffset dateTimeOffset: - writer.WriteStringValue(dateTimeOffset, "O"); - break; - case DateTime dateTime: - writer.WriteStringValue(dateTime, "O"); - break; - case IEnumerable> enumerable: - writer.WriteStartObject(); - foreach (var pair in enumerable) - { - writer.WritePropertyName(pair.Key); - writer.WriteObjectValue(pair.Value, options); - } - writer.WriteEndObject(); - break; - case IEnumerable objectEnumerable: - writer.WriteStartArray(); - foreach (var item in objectEnumerable) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - break; - case TimeSpan timeSpan: - writer.WriteStringValue(timeSpan, "P"); - break; - default: - throw new NotSupportedException($"Not supported type {value.GetType()}"); - } - } - - public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null) - { - writer.WriteObjectValue(value, options); - } - - public static BinaryData GetUtf8Bytes(this JsonElement element) - { -#if NET9_0_OR_GREATER - return new global::System.BinaryData(global::System.Runtime.InteropServices.JsonMarshal.GetRawUtf8Value(element).ToArray()); -#else - return BinaryData.FromString(element.GetRawText()); -#endif - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs deleted file mode 100644 index fc734a096a8..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/SerializationFormat.cs +++ /dev/null @@ -1,46 +0,0 @@ -// - -#nullable disable - -namespace Encode._Array -{ - internal enum SerializationFormat - { - /// The default serialization format. - Default = 0, - /// The RFC1123 date time format. - DateTime_RFC1123 = 1, - /// The RFC3339 date time format. - DateTime_RFC3339 = 2, - /// The RFC7231 date time format. - DateTime_RFC7231 = 3, - /// The ISO8601 date time format. - DateTime_ISO8601 = 4, - /// The Unix date time format. - DateTime_Unix = 5, - /// The ISO8601 date format. - Date_ISO8601 = 6, - /// The ISO8601 duration format. - Duration_ISO8601 = 7, - /// The constant duration format. - Duration_Constant = 8, - /// The seconds duration format. - Duration_Seconds = 9, - /// The seconds duration format with float precision. - Duration_Seconds_Float = 10, - /// The seconds duration format with double precision. - Duration_Seconds_Double = 11, - /// The milliseconds duration format. - Duration_Milliseconds = 12, - /// The milliseconds duration format with float precision. - Duration_Milliseconds_Float = 13, - /// The milliseconds duration format with double precision. - Duration_Milliseconds_Double = 14, - /// The ISO8601 time format. - Time_ISO8601 = 15, - /// The Base64Url bytes format. - Bytes_Base64Url = 16, - /// The Base64 bytes format. - Bytes_Base64 = 17 - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs deleted file mode 100644 index e50bce67d13..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Internal/TypeFormatters.cs +++ /dev/null @@ -1,177 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace Encode._Array -{ - internal static partial class TypeFormatters - { - private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ"; - public const string DefaultNumberFormat = "G"; - - public static string ToString(bool value) => value ? "true" : "false"; - - public static string ToString(DateTime value, string format) => value.Kind switch - { - DateTimeKind.Utc => ToString((DateTimeOffset)value, format), - _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") - }; - - public static string ToString(DateTimeOffset value, string format) => format switch - { - "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), - "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), - "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), - "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), - "R" => value.ToString("r", CultureInfo.InvariantCulture), - _ => value.ToString(format, CultureInfo.InvariantCulture) - }; - - public static string ToString(TimeSpan value, string format) => format switch - { - "P" => System.Xml.XmlConvert.ToString(value), - _ => value.ToString(format, CultureInfo.InvariantCulture) - }; - - public static string ToString(byte[] value, string format) => format switch - { - "U" => ToBase64UrlString(value), - "D" => Convert.ToBase64String(value), - _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) - }; - - public static string ToBase64UrlString(byte[] value) - { - int numWholeOrPartialInputBlocks = checked (value.Length + 2) / 3; - int size = checked (numWholeOrPartialInputBlocks * 4); - char[] output = new char[size]; - - int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0); - - int i = 0; - for (; i < numBase64Chars; i++) - { - char ch = output[i]; - if (ch == '+') - { - output[i] = '-'; - } - else - { - if (ch == '/') - { - output[i] = '_'; - } - else - { - if (ch == '=') - { - break; - } - } - } - } - - return new string(output, 0, i); - } - - public static byte[] FromBase64UrlString(string value) - { - int paddingCharsToAdd = (value.Length % 4) switch - { - 0 => 0, - 2 => 2, - 3 => 1, - _ => throw new InvalidOperationException("Malformed input") - }; - char[] output = new char[(value.Length + paddingCharsToAdd)]; - int i = 0; - for (; i < value.Length; i++) - { - char ch = value[i]; - if (ch == '-') - { - output[i] = '+'; - } - else - { - if (ch == '_') - { - output[i] = '/'; - } - else - { - output[i] = ch; - } - } - } - - for (; i < output.Length; i++) - { - output[i] = '='; - } - - return Convert.FromBase64CharArray(output, 0, output.Length); - } - - public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch - { - "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)), - _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) - }; - - public static TimeSpan ParseTimeSpan(string value, string format) => format switch - { - "P" => System.Xml.XmlConvert.ToTimeSpan(value), - _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture) - }; - - public static string ToFormatSpecifier(SerializationFormat format) => format switch - { - SerializationFormat.DateTime_RFC1123 => "R", - SerializationFormat.DateTime_RFC3339 => "O", - SerializationFormat.DateTime_RFC7231 => "R", - SerializationFormat.DateTime_ISO8601 => "O", - SerializationFormat.Date_ISO8601 => "D", - SerializationFormat.DateTime_Unix => "U", - SerializationFormat.Bytes_Base64Url => "U", - SerializationFormat.Bytes_Base64 => "D", - SerializationFormat.Duration_ISO8601 => "P", - SerializationFormat.Duration_Constant => "c", - SerializationFormat.Duration_Seconds => "%s", - SerializationFormat.Duration_Seconds_Float => "s\\.FFF", - SerializationFormat.Duration_Seconds_Double => "s\\.FFFFFF", - SerializationFormat.Time_ISO8601 => "T", - _ => null - }; - - public static string ConvertToString(object value, SerializationFormat format = SerializationFormat.Default) - { - string formatSpecifier = ToFormatSpecifier(format); - - return 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 formatSpecifier != null => ToString(b0, formatSpecifier), - IEnumerable s0 => string.Join(",", s0), - DateTimeOffset dateTime when formatSpecifier != null => ToString(dateTime, formatSpecifier), - TimeSpan timeSpan when format == SerializationFormat.Duration_Seconds => Convert.ToInt32(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture), - TimeSpan timeSpan0 when format == SerializationFormat.Duration_Seconds_Float || format == SerializationFormat.Duration_Seconds_Double => timeSpan0.TotalSeconds.ToString(CultureInfo.InvariantCulture), - TimeSpan timeSpan1 when format == SerializationFormat.Duration_Milliseconds => Convert.ToInt32(timeSpan1.TotalMilliseconds).ToString(CultureInfo.InvariantCulture), - TimeSpan timeSpan2 when format == SerializationFormat.Duration_Milliseconds_Float || format == SerializationFormat.Duration_Milliseconds_Double => timeSpan2.TotalMilliseconds.ToString(CultureInfo.InvariantCulture), - TimeSpan timeSpan3 when formatSpecifier != null => ToString(timeSpan3, formatSpecifier), - TimeSpan timeSpan4 => System.Xml.XmlConvert.ToString(timeSpan4), - Guid guid => guid.ToString(), - BinaryData binaryData => ConvertToString(binaryData.ToArray(), format), - _ => value.ToString() - }; - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs index 83b43fc67bf..c0c7fbd4732 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.Serialization.cs @@ -5,155 +5,34 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { - /// The CommaDelimitedArrayProperty. public partial class CommaDelimitedArrayProperty : IJsonModel { - /// Initializes a new instance of for deserialization. - internal CommaDelimitedArrayProperty() - { - } + internal CommaDelimitedArrayProperty() => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support writing '{format}' format."); - } - writer.WritePropertyName("value"u8); - writer.WriteStringValue(string.Join(",", Value)); - if (options.Format != "W" && _additionalBinaryDataProperties != null) - { - foreach (var item in _additionalBinaryDataProperties) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - } + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - CommaDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + CommaDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - protected virtual CommaDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeCommaDelimitedArrayProperty(document.RootElement, options); - } + protected virtual CommaDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON element to deserialize. - /// The client options for reading and writing models. - internal static CommaDelimitedArrayProperty DeserializeCommaDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IList value = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("value"u8)) - { - string stringValue = prop.Value.GetString(); - value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split(',')); - continue; - } - if (options.Format != "W") - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new CommaDelimitedArrayProperty(value, additionalBinaryDataProperties); - } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); - default: - throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support writing '{options.Format}' format."); - } - } + CommaDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - CommaDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + protected virtual CommaDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - protected virtual CommaDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) - { - return DeserializeCommaDelimitedArrayProperty(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(CommaDelimitedArrayProperty)} does not support reading '{options.Format}' format."); - } - } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + public static implicit operator BinaryContent(CommaDelimitedArrayProperty commaDelimitedArrayProperty) => throw null; - /// The to serialize into . - public static implicit operator BinaryContent(CommaDelimitedArrayProperty commaDelimitedArrayProperty) - { - if (commaDelimitedArrayProperty == null) - { - return null; - } - return BinaryContent.Create(commaDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); - } - - /// The to deserialize the from. - public static explicit operator CommaDelimitedArrayProperty(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); - return DeserializeCommaDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); - } + public static explicit operator CommaDelimitedArrayProperty(ClientResult result) => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs index 26b6300a619..9e62fadd600 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/CommaDelimitedArrayProperty.cs @@ -2,38 +2,14 @@ #nullable disable -using System; using System.Collections.Generic; -using System.Linq; namespace Encode._Array { - /// The CommaDelimitedArrayProperty. public partial class CommaDelimitedArrayProperty { - /// Keeps track of any properties unknown to the library. - private protected readonly IDictionary _additionalBinaryDataProperties; + public CommaDelimitedArrayProperty(IEnumerable value) => throw null; - /// Initializes a new instance of . - /// - /// is null. - public CommaDelimitedArrayProperty(IEnumerable value) - { - Argument.AssertNotNull(value, nameof(value)); - - Value = value.ToList(); - } - - /// Initializes a new instance of . - /// - /// Keeps track of any properties unknown to the library. - internal CommaDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) - { - Value = value; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - /// Gets the Value. - public IList Value { get; } + public IList Value => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs index 51c4d54b3a1..f3ab669d97b 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/Encode_ArrayContext.cs @@ -6,10 +6,6 @@ namespace Encode._Array { - /// - /// Context class which will be filled in by the System.ClientModel.SourceGeneration. - /// For more information - /// [ModelReaderWriterBuildable(typeof(CommaDelimitedArrayProperty))] [ModelReaderWriterBuildable(typeof(NewlineDelimitedArrayProperty))] [ModelReaderWriterBuildable(typeof(PipeDelimitedArrayProperty))] diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs index b53098449f6..cd31ef81498 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.Serialization.cs @@ -5,155 +5,34 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { - /// The NewlineDelimitedArrayProperty. public partial class NewlineDelimitedArrayProperty : IJsonModel { - /// Initializes a new instance of for deserialization. - internal NewlineDelimitedArrayProperty() - { - } + internal NewlineDelimitedArrayProperty() => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support writing '{format}' format."); - } - writer.WritePropertyName("value"u8); - writer.WriteStringValue(string.Join("\n", Value)); - if (options.Format != "W" && _additionalBinaryDataProperties != null) - { - foreach (var item in _additionalBinaryDataProperties) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - } + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - NewlineDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + NewlineDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - protected virtual NewlineDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeNewlineDelimitedArrayProperty(document.RootElement, options); - } + protected virtual NewlineDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON element to deserialize. - /// The client options for reading and writing models. - internal static NewlineDelimitedArrayProperty DeserializeNewlineDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IList value = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("value"u8)) - { - string stringValue = prop.Value.GetString(); - value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split('\n')); - continue; - } - if (options.Format != "W") - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new NewlineDelimitedArrayProperty(value, additionalBinaryDataProperties); - } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); - default: - throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support writing '{options.Format}' format."); - } - } + NewlineDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - NewlineDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + protected virtual NewlineDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - protected virtual NewlineDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) - { - return DeserializeNewlineDelimitedArrayProperty(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(NewlineDelimitedArrayProperty)} does not support reading '{options.Format}' format."); - } - } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + public static implicit operator BinaryContent(NewlineDelimitedArrayProperty newlineDelimitedArrayProperty) => throw null; - /// The to serialize into . - public static implicit operator BinaryContent(NewlineDelimitedArrayProperty newlineDelimitedArrayProperty) - { - if (newlineDelimitedArrayProperty == null) - { - return null; - } - return BinaryContent.Create(newlineDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); - } - - /// The to deserialize the from. - public static explicit operator NewlineDelimitedArrayProperty(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); - return DeserializeNewlineDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); - } + public static explicit operator NewlineDelimitedArrayProperty(ClientResult result) => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs index 677c73e072d..1680d3dcc06 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/NewlineDelimitedArrayProperty.cs @@ -2,38 +2,14 @@ #nullable disable -using System; using System.Collections.Generic; -using System.Linq; namespace Encode._Array { - /// The NewlineDelimitedArrayProperty. public partial class NewlineDelimitedArrayProperty { - /// Keeps track of any properties unknown to the library. - private protected readonly IDictionary _additionalBinaryDataProperties; + public NewlineDelimitedArrayProperty(IEnumerable value) => throw null; - /// Initializes a new instance of . - /// - /// is null. - public NewlineDelimitedArrayProperty(IEnumerable value) - { - Argument.AssertNotNull(value, nameof(value)); - - Value = value.ToList(); - } - - /// Initializes a new instance of . - /// - /// Keeps track of any properties unknown to the library. - internal NewlineDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) - { - Value = value; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - /// Gets the Value. - public IList Value { get; } + public IList Value => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs index 2c34cf35208..77fb59cc6da 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.Serialization.cs @@ -5,155 +5,34 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { - /// The PipeDelimitedArrayProperty. public partial class PipeDelimitedArrayProperty : IJsonModel { - /// Initializes a new instance of for deserialization. - internal PipeDelimitedArrayProperty() - { - } + internal PipeDelimitedArrayProperty() => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support writing '{format}' format."); - } - writer.WritePropertyName("value"u8); - writer.WriteStringValue(string.Join("|", Value)); - if (options.Format != "W" && _additionalBinaryDataProperties != null) - { - foreach (var item in _additionalBinaryDataProperties) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - } + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - PipeDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + PipeDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - protected virtual PipeDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializePipeDelimitedArrayProperty(document.RootElement, options); - } + protected virtual PipeDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON element to deserialize. - /// The client options for reading and writing models. - internal static PipeDelimitedArrayProperty DeserializePipeDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IList value = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("value"u8)) - { - string stringValue = prop.Value.GetString(); - value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split('|')); - continue; - } - if (options.Format != "W") - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new PipeDelimitedArrayProperty(value, additionalBinaryDataProperties); - } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); - default: - throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support writing '{options.Format}' format."); - } - } + PipeDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - PipeDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + protected virtual PipeDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - protected virtual PipeDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) - { - return DeserializePipeDelimitedArrayProperty(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(PipeDelimitedArrayProperty)} does not support reading '{options.Format}' format."); - } - } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + public static implicit operator BinaryContent(PipeDelimitedArrayProperty pipeDelimitedArrayProperty) => throw null; - /// The to serialize into . - public static implicit operator BinaryContent(PipeDelimitedArrayProperty pipeDelimitedArrayProperty) - { - if (pipeDelimitedArrayProperty == null) - { - return null; - } - return BinaryContent.Create(pipeDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); - } - - /// The to deserialize the from. - public static explicit operator PipeDelimitedArrayProperty(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); - return DeserializePipeDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); - } + public static explicit operator PipeDelimitedArrayProperty(ClientResult result) => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs index fcd20bf64c6..a8267bbaf53 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/PipeDelimitedArrayProperty.cs @@ -2,38 +2,14 @@ #nullable disable -using System; using System.Collections.Generic; -using System.Linq; namespace Encode._Array { - /// The PipeDelimitedArrayProperty. public partial class PipeDelimitedArrayProperty { - /// Keeps track of any properties unknown to the library. - private protected readonly IDictionary _additionalBinaryDataProperties; + public PipeDelimitedArrayProperty(IEnumerable value) => throw null; - /// Initializes a new instance of . - /// - /// is null. - public PipeDelimitedArrayProperty(IEnumerable value) - { - Argument.AssertNotNull(value, nameof(value)); - - Value = value.ToList(); - } - - /// Initializes a new instance of . - /// - /// Keeps track of any properties unknown to the library. - internal PipeDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) - { - Value = value; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - /// Gets the Value. - public IList Value { get; } + public IList Value => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs index dc4cd5a8ec5..d37d4f47a96 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.Serialization.cs @@ -5,155 +5,34 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; using System.Text.Json; namespace Encode._Array { - /// The SpaceDelimitedArrayProperty. public partial class SpaceDelimitedArrayProperty : IJsonModel { - /// Initializes a new instance of for deserialization. - internal SpaceDelimitedArrayProperty() - { - } + internal SpaceDelimitedArrayProperty() => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON writer. - /// The client options for reading and writing models. - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support writing '{format}' format."); - } - writer.WritePropertyName("value"u8); - writer.WriteStringValue(string.Join(" ", Value)); - if (options.Format != "W" && _additionalBinaryDataProperties != null) - { - foreach (var item in _additionalBinaryDataProperties) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - } + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - SpaceDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + SpaceDelimitedArrayProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON reader. - /// The client options for reading and writing models. - protected virtual SpaceDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeSpaceDelimitedArrayProperty(document.RootElement, options); - } + protected virtual SpaceDelimitedArrayProperty JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => throw null; - /// The JSON element to deserialize. - /// The client options for reading and writing models. - internal static SpaceDelimitedArrayProperty DeserializeSpaceDelimitedArrayProperty(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IList value = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("value"u8)) - { - string stringValue = prop.Value.GetString(); - value = string.IsNullOrEmpty(stringValue) ? new List() : new List(stringValue.Split(' ')); - continue; - } - if (options.Format != "W") - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new SpaceDelimitedArrayProperty(value, additionalBinaryDataProperties); - } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options, Encode_ArrayContext.Default); - default: - throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support writing '{options.Format}' format."); - } - } + SpaceDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - SpaceDelimitedArrayProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + protected virtual SpaceDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) => throw null; - /// The data to parse. - /// The client options for reading and writing models. - protected virtual SpaceDelimitedArrayProperty PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) - { - return DeserializeSpaceDelimitedArrayProperty(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(SpaceDelimitedArrayProperty)} does not support reading '{options.Format}' format."); - } - } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => throw null; - /// The client options for reading and writing models. - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + public static implicit operator BinaryContent(SpaceDelimitedArrayProperty spaceDelimitedArrayProperty) => throw null; - /// The to serialize into . - public static implicit operator BinaryContent(SpaceDelimitedArrayProperty spaceDelimitedArrayProperty) - { - if (spaceDelimitedArrayProperty == null) - { - return null; - } - return BinaryContent.Create(spaceDelimitedArrayProperty, ModelSerializationExtensions.WireOptions); - } - - /// The to deserialize the from. - public static explicit operator SpaceDelimitedArrayProperty(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); - return DeserializeSpaceDelimitedArrayProperty(document.RootElement, ModelSerializationExtensions.WireOptions); - } + public static explicit operator SpaceDelimitedArrayProperty(ClientResult result) => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs index c5dff570ab2..e93bddfb965 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Models/SpaceDelimitedArrayProperty.cs @@ -2,38 +2,14 @@ #nullable disable -using System; using System.Collections.Generic; -using System.Linq; namespace Encode._Array { - /// The SpaceDelimitedArrayProperty. public partial class SpaceDelimitedArrayProperty { - /// Keeps track of any properties unknown to the library. - private protected readonly IDictionary _additionalBinaryDataProperties; + public SpaceDelimitedArrayProperty(IEnumerable value) => throw null; - /// Initializes a new instance of . - /// - /// is null. - public SpaceDelimitedArrayProperty(IEnumerable value) - { - Argument.AssertNotNull(value, nameof(value)); - - Value = value.ToList(); - } - - /// Initializes a new instance of . - /// - /// Keeps track of any properties unknown to the library. - internal SpaceDelimitedArrayProperty(IList value, IDictionary additionalBinaryDataProperties) - { - Value = value; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - /// Gets the Value. - public IList Value { get; } + public IList Value => throw null; } } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs deleted file mode 100644 index 59896be6f55..00000000000 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.RestClient.cs +++ /dev/null @@ -1,74 +0,0 @@ -// - -#nullable disable - -using System.ClientModel; -using System.ClientModel.Primitives; -using Encode._Array; - -namespace Encode._Array._Property -{ - /// - public partial class Property - { - private static PipelineMessageClassifier _pipelineMessageClassifier200; - - private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); - - internal PipelineMessage CreateCommaDelimitedRequest(BinaryContent content, RequestOptions options) - { - ClientUriBuilder uri = new ClientUriBuilder(); - uri.Reset(_endpoint); - uri.AppendPath("/encode/array/property/comma-delimited", false); - PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); - PipelineRequest request = message.Request; - request.Headers.Set("Content-Type", "application/json"); - request.Headers.Set("Accept", "application/json"); - request.Content = content; - message.Apply(options); - return message; - } - - internal PipelineMessage CreateSpaceDelimitedRequest(BinaryContent content, RequestOptions options) - { - ClientUriBuilder uri = new ClientUriBuilder(); - uri.Reset(_endpoint); - uri.AppendPath("/encode/array/property/space-delimited", false); - PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); - PipelineRequest request = message.Request; - request.Headers.Set("Content-Type", "application/json"); - request.Headers.Set("Accept", "application/json"); - request.Content = content; - message.Apply(options); - return message; - } - - internal PipelineMessage CreatePipeDelimitedRequest(BinaryContent content, RequestOptions options) - { - ClientUriBuilder uri = new ClientUriBuilder(); - uri.Reset(_endpoint); - uri.AppendPath("/encode/array/property/pipe-delimited", false); - PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); - PipelineRequest request = message.Request; - request.Headers.Set("Content-Type", "application/json"); - request.Headers.Set("Accept", "application/json"); - request.Content = content; - message.Apply(options); - return message; - } - - internal PipelineMessage CreateNewlineDelimitedRequest(BinaryContent content, RequestOptions options) - { - ClientUriBuilder uri = new ClientUriBuilder(); - uri.Reset(_endpoint); - uri.AppendPath("/encode/array/property/newline-delimited", false); - PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "POST", PipelineMessageClassifier200); - PipelineRequest request = message.Request; - request.Headers.Set("Content-Type", "application/json"); - request.Headers.Set("Accept", "application/json"); - request.Content = content; - message.Apply(options); - return message; - } - } -} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs index 6c79d0514e1..e50400b6ee6 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/encode/array/src/Generated/Property.cs @@ -2,7 +2,6 @@ #nullable disable -using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Threading; @@ -11,298 +10,42 @@ namespace Encode._Array._Property { - /// The Property sub-client. public partial class Property { - private readonly Uri _endpoint; + protected Property() => throw null; - /// Initializes a new instance of Property for mocking. - protected Property() - { - } + public ClientPipeline Pipeline => throw null; - /// Initializes a new instance of Property. - /// The HTTP pipeline for sending and receiving REST requests and responses. - /// Service endpoint. - internal Property(ClientPipeline pipeline, Uri endpoint) - { - _endpoint = endpoint; - Pipeline = pipeline; - } + public virtual ClientResult CommaDelimited(BinaryContent content, RequestOptions options = null) => throw null; - /// The HTTP pipeline for sending and receiving REST requests and responses. - public ClientPipeline Pipeline { get; } + public virtual Task CommaDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; - /// - /// [Protocol Method] CommaDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 ClientResult CommaDelimited(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); + public virtual ClientResult CommaDelimited(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - using PipelineMessage message = CreateCommaDelimitedRequest(content, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } + public virtual Task> CommaDelimitedAsync(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - /// - /// [Protocol Method] CommaDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 CommaDelimitedAsync(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); + public virtual ClientResult SpaceDelimited(BinaryContent content, RequestOptions options = null) => throw null; - using PipelineMessage message = CreateCommaDelimitedRequest(content, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } + public virtual Task SpaceDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; - /// CommaDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual ClientResult CommaDelimited(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); + public virtual ClientResult SpaceDelimited(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - ClientResult result = CommaDelimited(body, cancellationToken.ToRequestOptions()); - return ClientResult.FromValue((CommaDelimitedArrayProperty)result, result.GetRawResponse()); - } + public virtual Task> SpaceDelimitedAsync(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - /// CommaDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual async Task> CommaDelimitedAsync(CommaDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); + public virtual ClientResult PipeDelimited(BinaryContent content, RequestOptions options = null) => throw null; - ClientResult result = await CommaDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); - return ClientResult.FromValue((CommaDelimitedArrayProperty)result, result.GetRawResponse()); - } + public virtual Task PipeDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; - /// - /// [Protocol Method] SpaceDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 ClientResult SpaceDelimited(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); + public virtual ClientResult PipeDelimited(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - using PipelineMessage message = CreateSpaceDelimitedRequest(content, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } + public virtual Task> PipeDelimitedAsync(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - /// - /// [Protocol Method] SpaceDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 SpaceDelimitedAsync(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); + public virtual ClientResult NewlineDelimited(BinaryContent content, RequestOptions options = null) => throw null; - using PipelineMessage message = CreateSpaceDelimitedRequest(content, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } + public virtual Task NewlineDelimitedAsync(BinaryContent content, RequestOptions options = null) => throw null; - /// SpaceDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual ClientResult SpaceDelimited(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); + public virtual ClientResult NewlineDelimited(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; - ClientResult result = SpaceDelimited(body, cancellationToken.ToRequestOptions()); - return ClientResult.FromValue((SpaceDelimitedArrayProperty)result, result.GetRawResponse()); - } - - /// SpaceDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual async Task> SpaceDelimitedAsync(SpaceDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); - - ClientResult result = await SpaceDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); - return ClientResult.FromValue((SpaceDelimitedArrayProperty)result, result.GetRawResponse()); - } - - /// - /// [Protocol Method] PipeDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 ClientResult PipeDelimited(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); - - using PipelineMessage message = CreatePipeDelimitedRequest(content, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } - - /// - /// [Protocol Method] PipeDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 PipeDelimitedAsync(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); - - using PipelineMessage message = CreatePipeDelimitedRequest(content, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - /// PipeDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual ClientResult PipeDelimited(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); - - ClientResult result = PipeDelimited(body, cancellationToken.ToRequestOptions()); - return ClientResult.FromValue((PipeDelimitedArrayProperty)result, result.GetRawResponse()); - } - - /// PipeDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual async Task> PipeDelimitedAsync(PipeDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); - - ClientResult result = await PipeDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); - return ClientResult.FromValue((PipeDelimitedArrayProperty)result, result.GetRawResponse()); - } - - /// - /// [Protocol Method] NewlineDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 ClientResult NewlineDelimited(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); - - using PipelineMessage message = CreateNewlineDelimitedRequest(content, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } - - /// - /// [Protocol Method] NewlineDelimited - /// - /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. - /// - /// - /// - /// The content to send as the body of the request. - /// The request options, 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 NewlineDelimitedAsync(BinaryContent content, RequestOptions options = null) - { - Argument.AssertNotNull(content, nameof(content)); - - using PipelineMessage message = CreateNewlineDelimitedRequest(content, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - /// NewlineDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual ClientResult NewlineDelimited(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); - - ClientResult result = NewlineDelimited(body, cancellationToken.ToRequestOptions()); - return ClientResult.FromValue((NewlineDelimitedArrayProperty)result, result.GetRawResponse()); - } - - /// NewlineDelimited. - /// - /// The cancellation token that can be used to cancel the operation. - /// is null. - /// Service returned a non-success status code. - public virtual async Task> NewlineDelimitedAsync(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) - { - Argument.AssertNotNull(body, nameof(body)); - - ClientResult result = await NewlineDelimitedAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); - return ClientResult.FromValue((NewlineDelimitedArrayProperty)result, result.GetRawResponse()); - } + public virtual Task> NewlineDelimitedAsync(NewlineDelimitedArrayProperty body, CancellationToken cancellationToken = default) => throw null; } } From 4be78880fad7d9eb29949223fbe98a8af083d5b8 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 26 Jan 2026 09:34:19 -0800 Subject: [PATCH 4/8] serealization format used --- .../MrwSerializationTypeDefinition.cs | 40 +++++++++++++++---- .../Serialization/SerializationFormat.cs | 4 ++ .../src/Primitives/PropertyWireInformation.cs | 5 +-- .../src/Providers/PropertyProvider.cs | 24 ++++++++++- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs index 4b65a80c4c4..ab35ab7b9a4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs @@ -969,7 +969,7 @@ private List BuildDeserializePropertiesStatements(ScopedApi var propertyExpression = parameter.Property?.AsVariableExpression ?? parameter.Field?.AsVariableExpression; var checkIfJsonPropEqualsName = new IfStatement(jsonProperty.NameEquals(propertySerializationName)) { - DeserializeProperty(propertyName!, propertyType!, wireInfo, propertyExpression!, jsonProperty, serializationAttributes) + DeserializeProperty(propertyName!, propertyType!, wireInfo, propertyExpression!, jsonProperty, serializationAttributes, parameter.Property) }; propertyDeserializationStatements.Add(checkIfJsonPropEqualsName); } @@ -1285,7 +1285,8 @@ private MethodBodyStatement[] DeserializeProperty( PropertyWireInformation wireInfo, VariableExpression variableExpression, ScopedApi jsonProperty, - IEnumerable serializationAttributes) + IEnumerable serializationAttributes, + PropertyProvider? propertyProvider = null) { bool useCustomDeserializationHook = false; var serializationFormat = wireInfo.SerializationFormat; @@ -1294,13 +1295,14 @@ private MethodBodyStatement[] DeserializeProperty( MethodBodyStatement[] deserializationStatements; // Check for encoded arrays and use custom deserialization logic - if (!string.IsNullOrEmpty(wireInfo.Encode) && (propertyType.IsList || propertyType.IsArray)) + if (propertyProvider != null && IsArrayEncodingFormat(propertyProvider.SerializationFormat) && (propertyType.IsList || propertyType.IsArray)) { + var arrayEncoding = GetArrayEncodingString(propertyProvider.SerializationFormat); deserializationStatements = CreateEncodedArrayDeserializationStatements( propertyType, propertyVarReference, jsonProperty, - wireInfo.Encode); + arrayEncoding); } else { @@ -1618,7 +1620,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode continue; } - propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property)); + propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, property)); } foreach (var field in _model.CanonicalView.Fields) @@ -1638,7 +1640,8 @@ private MethodBodyStatement CreateWritePropertyStatement( PropertyWireInformation wireInfo, CSharpType propertyType, string propertyName, - MemberExpression propertyExpression) + MemberExpression propertyExpression, + PropertyProvider? propertyProvider = null) { var propertySerializationName = wireInfo.SerializedName; var propertySerializationFormat = wireInfo.SerializationFormat; @@ -1650,12 +1653,13 @@ private MethodBodyStatement CreateWritePropertyStatement( var serializationStatement = CreateSerializationStatement(propertyType, propertyExpression, propertySerializationFormat, propertySerializationName); // Check for encoded arrays and override the serialization statement - if (!string.IsNullOrEmpty(wireInfo.Encode) && (propertyType.IsList || propertyType.IsArray)) + if (propertyProvider != null && IsArrayEncodingFormat(propertyProvider.SerializationFormat) && (propertyType.IsList || propertyType.IsArray)) { + var arrayEncoding = GetArrayEncodingString(propertyProvider.SerializationFormat); serializationStatement = CreateEncodedArraySerializationStatement( propertyType, propertyExpression, - wireInfo.Encode); + arrayEncoding); } // Check for custom serialization hooks @@ -2418,5 +2422,25 @@ provider is ModelProvider modelProvider ? GetDeserializationMethodInvocationForType(modelProvider, jsonElementVariable, dataVariable, optionsVariable) : modelType.Deserialize(jsonElementVariable, null, optionsVariable); } + + private static bool IsArrayEncodingFormat(SerializationFormat format) + { + return format is SerializationFormat.Array_CommaDelimited or + SerializationFormat.Array_SpaceDelimited or + SerializationFormat.Array_PipeDelimited or + SerializationFormat.Array_NewlineDelimited; + } + + private static string GetArrayEncodingString(SerializationFormat format) + { + return format switch + { + SerializationFormat.Array_CommaDelimited => "commaDelimited", + SerializationFormat.Array_SpaceDelimited => "spaceDelimited", + SerializationFormat.Array_PipeDelimited => "pipeDelimited", + SerializationFormat.Array_NewlineDelimited => "newlineDelimited", + _ => throw new ArgumentException($"Unsupported array encoding format: {format}") + }; + } } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/SerializationFormat.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/SerializationFormat.cs index 3497fe41243..18199def355 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/SerializationFormat.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/SerializationFormat.cs @@ -28,5 +28,9 @@ public enum SerializationFormat Bytes_Base64Url, Bytes_Base64, Int_String, + Array_CommaDelimited, + Array_SpaceDelimited, + Array_PipeDelimited, + Array_NewlineDelimited, } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs index a6fa1a37d97..336f4d3968f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs @@ -14,9 +14,8 @@ public class PropertyWireInformation : WireInformation public bool IsNullable { get; } public bool IsDiscriminator { get; } public bool IsHttpMetadata { get; } - public string? Encode { get; } internal FormattableString? Description { get; } - public PropertyWireInformation(SerializationFormat serializationFormat, bool isRequired, bool isReadOnly, bool isNullable, bool isDiscriminator, string serializedName, bool isHttpMetadata, string? encode = null) + public PropertyWireInformation(SerializationFormat serializationFormat, bool isRequired, bool isReadOnly, bool isNullable, bool isDiscriminator, string serializedName, bool isHttpMetadata) : base(serializationFormat, serializedName) { IsRequired = isRequired; @@ -24,7 +23,6 @@ public PropertyWireInformation(SerializationFormat serializationFormat, bool isR IsNullable = isNullable; IsDiscriminator = isDiscriminator; IsHttpMetadata = isHttpMetadata; - Encode = encode; } /// @@ -41,7 +39,6 @@ internal PropertyWireInformation(InputProperty inputProperty) IsHttpMetadata = modelProperty != null && modelProperty.IsHttpMetadata; IsNullable = inputProperty.Type is InputNullableType; IsDiscriminator = modelProperty != null && modelProperty.IsDiscriminator; - Encode = modelProperty?.Encode; Description = DocHelpers.GetFormattableDescription(inputProperty.Summary, inputProperty.Doc); } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs index 3f4b7d13a4b..db2e2b559d4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs @@ -39,6 +39,7 @@ public class PropertyProvider public FieldProvider? BackingField { get; set; } public PropertyProvider? BaseProperty { get; set; } public bool IsRef { get; private set; } + public SerializationFormat SerializationFormat => _serializationFormat; /// /// Converts this property to a parameter. @@ -91,7 +92,7 @@ private PropertyProvider(InputProperty inputProperty, CSharpType propertyType, T } EnclosingType = enclosingType; - _serializationFormat = CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type); + _serializationFormat = GetSerializationFormat(inputProperty); _isRequiredNonNullableConstant = inputProperty.IsRequired && propertyType is { IsLiteral: true, IsNullable: false }; var propHasSetter = PropertyHasSetter(propertyType, inputProperty); MethodSignatureModifiers setterModifier = propHasSetter ? MethodSignatureModifiers.Public : MethodSignatureModifiers.None; @@ -334,5 +335,26 @@ public void Update( BuildDocs(); } } + + private SerializationFormat GetSerializationFormat(InputProperty inputProperty) + { + // Handle array encoding from InputModelProperty + if (inputProperty is InputModelProperty modelProperty && + inputProperty.Type is InputArrayType && + !string.IsNullOrEmpty(modelProperty.Encode)) + { + return modelProperty.Encode switch + { + "commaDelimited" => SerializationFormat.Array_CommaDelimited, + "spaceDelimited" => SerializationFormat.Array_SpaceDelimited, + "pipeDelimited" => SerializationFormat.Array_PipeDelimited, + "newlineDelimited" => SerializationFormat.Array_NewlineDelimited, + _ => CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type) + }; + } + + // Use default serialization format logic + return CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type); + } } } From b2757daa4d9fc8b3b3cd2e019c2865d1cca404e4 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 26 Jan 2026 21:49:48 -0800 Subject: [PATCH 5/8] Refactoring --- .../MrwSerializationTypeDefinition.cs | 179 ++++++++++-------- 1 file changed, 95 insertions(+), 84 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs index ab35ab7b9a4..6c5c2dee6a0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs @@ -969,7 +969,7 @@ private List BuildDeserializePropertiesStatements(ScopedApi var propertyExpression = parameter.Property?.AsVariableExpression ?? parameter.Field?.AsVariableExpression; var checkIfJsonPropEqualsName = new IfStatement(jsonProperty.NameEquals(propertySerializationName)) { - DeserializeProperty(propertyName!, propertyType!, wireInfo, propertyExpression!, jsonProperty, serializationAttributes, parameter.Property) + DeserializeProperty(propertyName!, propertyType!, wireInfo, propertyExpression!, jsonProperty, serializationAttributes, parameter.Property?.SerializationFormat) }; propertyDeserializationStatements.Add(checkIfJsonPropEqualsName); } @@ -1286,33 +1286,11 @@ private MethodBodyStatement[] DeserializeProperty( VariableExpression variableExpression, ScopedApi jsonProperty, IEnumerable serializationAttributes, - PropertyProvider? propertyProvider = null) + SerializationFormat? arrayEncoding = null) { - bool useCustomDeserializationHook = false; var serializationFormat = wireInfo.SerializationFormat; - var propertyVarReference = variableExpression; - - MethodBodyStatement[] deserializationStatements; - - // Check for encoded arrays and use custom deserialization logic - if (propertyProvider != null && IsArrayEncodingFormat(propertyProvider.SerializationFormat) && (propertyType.IsList || propertyType.IsArray)) - { - var arrayEncoding = GetArrayEncodingString(propertyProvider.SerializationFormat); - deserializationStatements = CreateEncodedArrayDeserializationStatements( - propertyType, - propertyVarReference, - jsonProperty, - arrayEncoding); - } - else - { - deserializationStatements = new MethodBodyStatement[2] - { - DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), - propertyVarReference.Assign(value).Terminate() - }; - } + // Check for custom deserialization foreach (var attribute in serializationAttributes) { if (CodeGenAttributes.TryGetCodeGenSerializationAttributeValue( @@ -1323,21 +1301,48 @@ private MethodBodyStatement[] DeserializeProperty( out var deserializationHook, out _) && name == propertyName && deserializationHook != null) { + return + [ + MethodBodyStatement.Empty, + Static().Invoke(deserializationHook, jsonProperty, ByRef(variableExpression)).Terminate(), + Continue + ]; + } + } + + MethodBodyStatement[] deserializationStatements; + if (arrayEncoding.HasValue && IsArrayEncodingFormat(arrayEncoding.Value) && + (propertyType.IsList || propertyType.IsArray)) + { + var elementType = GetCollectionElementType(propertyType); + if (IsSupportedEncodedArrayElementType(elementType)) + { + deserializationStatements = CreateEncodedArrayDeserializationStatements( + propertyType, variableExpression, jsonProperty, arrayEncoding.Value); + } + else + { + // Fall back to default deserialization for unsupported element types deserializationStatements = - [Static().Invoke( - deserializationHook, - jsonProperty, - ByRef(propertyVarReference)).Terminate()]; - useCustomDeserializationHook = true; - break; + [ + DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), + variableExpression.Assign(value).Terminate() + ]; } } + else + { + // Default deserialization for non-encoded arrays and other types + deserializationStatements = + [ + DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), + variableExpression.Assign(value).Terminate() + ]; + } return [ - useCustomDeserializationHook - ? MethodBodyStatement.Empty - : DeserializationPropertyNullCheckStatement(propertyType, wireInfo, jsonProperty, propertyVarReference), + DeserializationPropertyNullCheckStatement(propertyType, wireInfo, jsonProperty, variableExpression), deserializationStatements, Continue ]; @@ -1595,7 +1600,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode { continue; } - propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property)); + propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, null)); } foreach (var field in baseModelProvider.CanonicalView.Fields) @@ -1604,7 +1609,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode { continue; } - propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field)); + propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, null)); } baseModelProvider = baseModelProvider.BaseModelProvider; @@ -1620,7 +1625,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode continue; } - propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, property)); + propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, property.SerializationFormat)); } foreach (var field in _model.CanonicalView.Fields) @@ -1630,7 +1635,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode continue; } - propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field)); + propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, null)); } return [.. propertyStatements]; @@ -1641,7 +1646,7 @@ private MethodBodyStatement CreateWritePropertyStatement( CSharpType propertyType, string propertyName, MemberExpression propertyExpression, - PropertyProvider? propertyProvider = null) + SerializationFormat? arrayEncoding = null) { var propertySerializationName = wireInfo.SerializedName; var propertySerializationFormat = wireInfo.SerializationFormat; @@ -1653,13 +1658,16 @@ private MethodBodyStatement CreateWritePropertyStatement( var serializationStatement = CreateSerializationStatement(propertyType, propertyExpression, propertySerializationFormat, propertySerializationName); // Check for encoded arrays and override the serialization statement - if (propertyProvider != null && IsArrayEncodingFormat(propertyProvider.SerializationFormat) && (propertyType.IsList || propertyType.IsArray)) + if (arrayEncoding.HasValue && IsArrayEncodingFormat(arrayEncoding.Value) && (propertyType.IsList || propertyType.IsArray)) { - var arrayEncoding = GetArrayEncodingString(propertyProvider.SerializationFormat); - serializationStatement = CreateEncodedArraySerializationStatement( - propertyType, - propertyExpression, - arrayEncoding); + var elementType = GetCollectionElementType(propertyType); + if (IsSupportedEncodedArrayElementType(elementType)) + { + serializationStatement = CreateEncodedArraySerializationStatement( + propertyType, + propertyExpression, + arrayEncoding.Value); + } } // Check for custom serialization hooks @@ -1838,23 +1846,41 @@ private MethodBodyStatement CreateListSerialization( }; } + private static bool IsSupportedEncodedArrayElementType(CSharpType elementType) + { + // Support string arrays + if (elementType.IsFrameworkType && elementType.FrameworkType == typeof(string)) + return true; + + // Support string enum arrays + if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) + return true; + + return false; + } + + private static CSharpType GetCollectionElementType(CSharpType collectionType) + { + return collectionType.IsArray ? collectionType.ElementType : collectionType.Arguments[0]; + } + private MethodBodyStatement CreateEncodedArraySerializationStatement( CSharpType propertyType, ValueExpression propertyExpression, - string encoding) + SerializationFormat encoding) { // Get the delimiter based on the encoding type var delimiter = encoding switch { - "commaDelimited" => ",", - "spaceDelimited" => " ", - "pipeDelimited" => "|", - "newlineDelimited" => "\n", + SerializationFormat.Array_CommaDelimited => ",", + SerializationFormat.Array_SpaceDelimited => " ", + SerializationFormat.Array_PipeDelimited => "|", + SerializationFormat.Array_NewlineDelimited => "\n", _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") }; // Get element type for string conversion - var elementType = propertyType.IsArray ? propertyType.ElementType : propertyType.Arguments[0]; + var elementType = GetCollectionElementType(propertyType); // Build the serialization expression based on element type ValueExpression stringJoinExpression; @@ -1864,10 +1890,9 @@ private MethodBodyStatement CreateEncodedArraySerializationStatement( // string.Join(",", array) stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), propertyExpression); } - else + else if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) { - // For non-string arrays, convert each element to string first - // string.Join(",", array.Select(x => x?.ToString() ?? "")) + // For string enum arrays, convert each enum to string first var x = new VariableExpression(typeof(object), "x"); var selectExpression = propertyExpression.Invoke("Select", new FuncExpression([x.Declaration], new TernaryConditionalExpression( @@ -1876,6 +1901,10 @@ private MethodBodyStatement CreateEncodedArraySerializationStatement( x.Invoke("ToString")))); stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), selectExpression); } + else + { + throw new InvalidOperationException($"Encoded array serialization is only supported for string and string enum arrays. Element type: {elementType.Name}"); + } // writer.WriteStringValue(stringJoinExpression) return _utf8JsonWriterSnippet.WriteStringValue(stringJoinExpression); @@ -1885,17 +1914,17 @@ private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( CSharpType propertyType, VariableExpression variableExpression, ScopedApi jsonProperty, - string encoding) + SerializationFormat encoding) { var delimiter = encoding switch { - "commaDelimited" => ",", - "spaceDelimited" => " ", - "pipeDelimited" => "|", - "newlineDelimited" => "\n", + SerializationFormat.Array_CommaDelimited => ",", + SerializationFormat.Array_SpaceDelimited => " ", + SerializationFormat.Array_PipeDelimited => "|", + SerializationFormat.Array_NewlineDelimited => "\n", _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") }; - var elementType = propertyType.IsArray ? propertyType.ElementType : propertyType.Arguments[0]; + var elementType = GetCollectionElementType(propertyType); var delimiterChar = Literal(delimiter.ToCharArray()[0]); var isStringElement = elementType.IsFrameworkType && elementType.FrameworkType == typeof(string); @@ -1930,7 +1959,7 @@ private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( createArrayStatement = variableExpression.Assign(New.Instance(propertyType, conditionalExpression)).Terminate(); } } - else + else if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) { var splitExpression = new TernaryConditionalExpression( isNullOrEmptyCheck, @@ -1940,17 +1969,7 @@ private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( var s = new VariableExpression(typeof(string), "s"); var trimmedS = s.Invoke("Trim"); - var parseExpression = elementType.IsFrameworkType - ? elementType.FrameworkType.Name switch - { - nameof(Int32) => Static().Invoke("Parse", trimmedS), - nameof(Int64) => Static().Invoke("Parse", trimmedS), - nameof(Double) => Static().Invoke("Parse", trimmedS), - nameof(Single) => Static().Invoke("Parse", trimmedS), - nameof(Boolean) => Static().Invoke("Parse", trimmedS), - _ => throw new InvalidOperationException($"Unsupported primitive type: {elementType.FrameworkType}") - } - : Static(elementType).Invoke("Parse", trimmedS); // Custom types + var parseExpression = Static(elementType).Invoke("Parse", trimmedS); var selectExpression = splitExpression.Invoke("Select", new FuncExpression([s.Declaration], parseExpression)); @@ -1962,6 +1981,10 @@ private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( : New.Instance(propertyType, selectExpression); createArrayStatement = variableExpression.Assign(finalExpression).Terminate(); } + else + { + throw new InvalidOperationException($"Encoded array deserialization is only supported for string and string enum arrays. Element type: {elementType.Name}"); + } return [ getStringStatement, @@ -2430,17 +2453,5 @@ SerializationFormat.Array_SpaceDelimited or SerializationFormat.Array_PipeDelimited or SerializationFormat.Array_NewlineDelimited; } - - private static string GetArrayEncodingString(SerializationFormat format) - { - return format switch - { - SerializationFormat.Array_CommaDelimited => "commaDelimited", - SerializationFormat.Array_SpaceDelimited => "spaceDelimited", - SerializationFormat.Array_PipeDelimited => "pipeDelimited", - SerializationFormat.Array_NewlineDelimited => "newlineDelimited", - _ => throw new ArgumentException($"Unsupported array encoding format: {format}") - }; - } } } From 434bb4a52155256aaf4ce763b25e4e0b1cb086c7 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 26 Jan 2026 22:11:45 -0800 Subject: [PATCH 6/8] refactoring --- .../src/Providers/MrwSerializationTypeDefinition.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs index 6c5c2dee6a0..0035c966306 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs @@ -1892,13 +1892,13 @@ private MethodBodyStatement CreateEncodedArraySerializationStatement( } else if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) { - // For string enum arrays, convert each enum to string first + // For string enum arrays, convert each enum to string var x = new VariableExpression(typeof(object), "x"); var selectExpression = propertyExpression.Invoke("Select", new FuncExpression([x.Declaration], new TernaryConditionalExpression( x.Equal(Null), Literal(""), - x.Invoke("ToString")))); + x.Invoke("ToSerialString")))); stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), selectExpression); } else From 4013b4a31fac1f9b057b28e0388e2c30d87b13bc Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 29 Jan 2026 09:23:28 -0800 Subject: [PATCH 7/8] added unit tests --- .../ModelCustomizationTests.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/ModelCustomizationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/ModelCustomizationTests.cs index fcff349c3f3..141a731d1d9 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/ModelCustomizationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/ModelCustomizationTests.cs @@ -526,5 +526,62 @@ public async Task ExplicitOperatorDoesNotPreventImplicit() m.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Operator)); Assert.IsNotNull(implicitOperator, "Implicit operator should still be generated when only explicit operator is customized"); } + + // Unit test for enum array serialization - shows generated output like spector tests show behavior + [Test] + public async Task ValidateEnumArraySerializationGeneratedOutput() + { + var inputEnum = InputFactory.StringEnum("TestEnum", [("Blue", "blue"), ("Red", "red"), ("Green", "green")], isExtensible: false); + var props = new[] + { + InputFactory.Property("Colors", InputFactory.Array(inputEnum)) + }; + + var inputModel = InputFactory.Model("mockInputModel", properties: props, usage: InputModelTypeUsage.Json); + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModels: () => [inputModel], + inputEnums: () => [inputEnum]); + + var modelProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t is ModelProvider); + var serializationProvider = modelProvider.SerializationProviders.Single(t => t is MrwSerializationTypeDefinition); + + var writer = new TypeProviderWriter(serializationProvider); + var file = writer.Write(); + + var generatedCode = file.Content; + + Assert.IsTrue(generatedCode.Contains("writer.WriteStringValue(item.ToSerialString())")); + Assert.IsTrue(generatedCode.Contains("array.Add(item.GetString().ToTestEnum())")); + Assert.IsTrue(generatedCode.Contains("foreach")); + Assert.IsTrue(generatedCode.Contains("ToSerialString()")); + } + + [Test] + public async Task ValidateEnumArrayDeserializationGeneratedOutput() + { + var inputEnum = InputFactory.StringEnum("TestEnum", [("Blue", "blue"), ("Red", "red"), ("Green", "green")], isExtensible: false); + var props = new[] + { + InputFactory.Property("Colors", InputFactory.Array(inputEnum)) + }; + + var inputModel = InputFactory.Model("mockInputModel", properties: props, usage: InputModelTypeUsage.Json); + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModels: () => [inputModel], + inputEnums: () => [inputEnum]); + + var modelProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t is ModelProvider); + var serializationProvider = modelProvider.SerializationProviders.Single(t => t is MrwSerializationTypeDefinition); + + var writer = new TypeProviderWriter(serializationProvider); + var file = writer.Write(); + + var generatedCode = file.Content; + + Assert.IsTrue(generatedCode.Contains("array.Add(item.GetString().ToTestEnum())")); + Assert.IsTrue(generatedCode.Contains("foreach")); + Assert.IsTrue(generatedCode.Contains("JsonElement")); + Assert.IsTrue(generatedCode.Contains("ToTestEnum()") || generatedCode.Contains(".ToEnum()")); + } } } From 759da0767a9ef309f572c013f204a8bf55523e42 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 29 Jan 2026 23:13:17 -0800 Subject: [PATCH 8/8] refactored code --- .../MrwSerializationTypeDefinition.cs | 160 +++++++++--------- .../ArrayKnownEncodingExtensions.cs | 68 ++++++++ .../src/InputTypes/ArrayKnownEncoding.cs | 31 ++++ .../src/InputTypes/InputModelProperty.cs | 11 ++ .../src/Providers/PropertyProvider.cs | 15 +- .../src/Snippets/StringSnippets.cs | 6 + 6 files changed, 200 insertions(+), 91 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/Extensions/ArrayKnownEncodingExtensions.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ArrayKnownEncoding.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs index 0035c966306..fc3e049782f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs @@ -1311,18 +1311,30 @@ private MethodBodyStatement[] DeserializeProperty( } MethodBodyStatement[] deserializationStatements; - if (arrayEncoding.HasValue && IsArrayEncodingFormat(arrayEncoding.Value) && - (propertyType.IsList || propertyType.IsArray)) + if (arrayEncoding.HasValue && (propertyType.IsList || propertyType.IsArray)) { - var elementType = GetCollectionElementType(propertyType); - if (IsSupportedEncodedArrayElementType(elementType)) + try { - deserializationStatements = CreateEncodedArrayDeserializationStatements( - propertyType, variableExpression, jsonProperty, arrayEncoding.Value); + var delimiter = ArrayKnownEncodingExtensions.GetDelimiter(arrayEncoding.Value); + var elementType = propertyType.ElementType; + if (IsSupportedEncodedArrayElementType(elementType)) + { + deserializationStatements = CreateEncodedArrayDeserializationStatements( + propertyType, variableExpression, jsonProperty, arrayEncoding.Value); + } + else + { + // Fall back to default deserialization for unsupported element types + deserializationStatements = + [ + DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), + variableExpression.Assign(value).Terminate() + ]; + } } - else + catch (ArgumentOutOfRangeException) { - // Fall back to default deserialization for unsupported element types + // Fall back to default deserialization for non-array encoding formats deserializationStatements = [ DeserializeValue(propertyType, jsonProperty.Value(), serializationFormat, out ValueExpression value), @@ -1600,7 +1612,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode { continue; } - propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, null)); + propertyStatements.Add(CreateWritePropertyStatement(property.WireInfo, property.Type, property.Name, property, property.WireInfo?.SerializationFormat)); } foreach (var field in baseModelProvider.CanonicalView.Fields) @@ -1609,7 +1621,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode { continue; } - propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, null)); + propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, field.WireInfo?.SerializationFormat)); } baseModelProvider = baseModelProvider.BaseModelProvider; @@ -1635,7 +1647,7 @@ private MethodBodyStatement[] CreateWritePropertiesStatements(bool isDynamicMode continue; } - propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, null)); + propertyStatements.Add(CreateWritePropertyStatement(field.WireInfo, field.Type, field.Name, field, field.WireInfo?.SerializationFormat)); } return [.. propertyStatements]; @@ -1646,7 +1658,7 @@ private MethodBodyStatement CreateWritePropertyStatement( CSharpType propertyType, string propertyName, MemberExpression propertyExpression, - SerializationFormat? arrayEncoding = null) + SerializationFormat? serializationFormat) { var propertySerializationName = wireInfo.SerializedName; var propertySerializationFormat = wireInfo.SerializationFormat; @@ -1658,15 +1670,23 @@ private MethodBodyStatement CreateWritePropertyStatement( var serializationStatement = CreateSerializationStatement(propertyType, propertyExpression, propertySerializationFormat, propertySerializationName); // Check for encoded arrays and override the serialization statement - if (arrayEncoding.HasValue && IsArrayEncodingFormat(arrayEncoding.Value) && (propertyType.IsList || propertyType.IsArray)) + if (serializationFormat.HasValue && (propertyType.IsList || propertyType.IsArray)) { - var elementType = GetCollectionElementType(propertyType); - if (IsSupportedEncodedArrayElementType(elementType)) + try + { + var delimiter = ArrayKnownEncodingExtensions.GetDelimiter(serializationFormat.Value); + var elementType = propertyType.ElementType; + if (IsSupportedEncodedArrayElementType(elementType)) + { + serializationStatement = CreateEncodedArraySerializationStatement( + propertyType, + propertyExpression, + serializationFormat.Value); + } + } + catch (ArgumentOutOfRangeException) { - serializationStatement = CreateEncodedArraySerializationStatement( - propertyType, - propertyExpression, - arrayEncoding.Value); + // Not an array encoding format, continue with regular serialization } } @@ -1850,63 +1870,51 @@ private static bool IsSupportedEncodedArrayElementType(CSharpType elementType) { // Support string arrays if (elementType.IsFrameworkType && elementType.FrameworkType == typeof(string)) + { return true; + } // Support string enum arrays - if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) + if (elementType.IsEnum && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) + { return true; - + } return false; } - private static CSharpType GetCollectionElementType(CSharpType collectionType) - { - return collectionType.IsArray ? collectionType.ElementType : collectionType.Arguments[0]; - } - private MethodBodyStatement CreateEncodedArraySerializationStatement( CSharpType propertyType, ValueExpression propertyExpression, - SerializationFormat encoding) + SerializationFormat serializationFormat) { - // Get the delimiter based on the encoding type - var delimiter = encoding switch - { - SerializationFormat.Array_CommaDelimited => ",", - SerializationFormat.Array_SpaceDelimited => " ", - SerializationFormat.Array_PipeDelimited => "|", - SerializationFormat.Array_NewlineDelimited => "\n", - _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") - }; + var delimiter = ArrayKnownEncodingExtensions.GetDelimiter(serializationFormat); - // Get element type for string conversion - var elementType = GetCollectionElementType(propertyType); + var elementType = propertyType.ElementType; - // Build the serialization expression based on element type ValueExpression stringJoinExpression; if (elementType.IsFrameworkType && elementType.FrameworkType == typeof(string)) { - // For string arrays, use string.Join directly - // string.Join(",", array) - stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), propertyExpression); + stringJoinExpression = StringSnippets.Join(Literal(delimiter), propertyExpression); } else if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) { - // For string enum arrays, convert each enum to string var x = new VariableExpression(typeof(object), "x"); - var selectExpression = propertyExpression.Invoke("Select", + var selectExpression = propertyExpression.Invoke(nameof(Enumerable.Select), new FuncExpression([x.Declaration], new TernaryConditionalExpression( x.Equal(Null), Literal(""), - x.Invoke("ToSerialString")))); - stringJoinExpression = Static().Invoke(nameof(string.Join), Literal(delimiter), selectExpression); + elementType.ToSerial(x)))); + stringJoinExpression = StringSnippets.Join(Literal(delimiter), selectExpression); } else { - throw new InvalidOperationException($"Encoded array serialization is only supported for string and string enum arrays. Element type: {elementType.Name}"); + ScmCodeModelGenerator.Instance.Emitter.ReportDiagnostic( + DiagnosticCodes.UnsupportedSerialization, + $"Encoded array serialization is only supported for string and string enum arrays. Element type: {elementType.Name}.", + severity: EmitterDiagnosticSeverity.Warning); + stringJoinExpression = propertyExpression.InvokeToString(); } - // writer.WriteStringValue(stringJoinExpression) return _utf8JsonWriterSnippet.WriteStringValue(stringJoinExpression); } @@ -1914,76 +1922,74 @@ private MethodBodyStatement[] CreateEncodedArrayDeserializationStatements( CSharpType propertyType, VariableExpression variableExpression, ScopedApi jsonProperty, - SerializationFormat encoding) + SerializationFormat serializationFormat) { - var delimiter = encoding switch - { - SerializationFormat.Array_CommaDelimited => ",", - SerializationFormat.Array_SpaceDelimited => " ", - SerializationFormat.Array_PipeDelimited => "|", - SerializationFormat.Array_NewlineDelimited => "\n", - _ => throw new InvalidOperationException($"Unknown array encoding: {encoding}") - }; - var elementType = GetCollectionElementType(propertyType); + var delimiter = ArrayKnownEncodingExtensions.GetDelimiter(serializationFormat); + var elementType = propertyType.ElementType; var delimiterChar = Literal(delimiter.ToCharArray()[0]); var isStringElement = elementType.IsFrameworkType && elementType.FrameworkType == typeof(string); var getStringStatement = Declare("stringValue", typeof(string), jsonProperty.Value().GetString(), out var stringValueVar); - var isNullOrEmptyCheck = Static().Invoke("IsNullOrEmpty", stringValueVar); + var isNullOrEmptyCheck = StringSnippets.IsNullOrEmpty(stringValueVar.As()); MethodBodyStatement createArrayStatement; if (isStringElement) { - var splitResult = stringValueVar.Invoke("Split", delimiterChar); + var splitResult = stringValueVar.As().Split(delimiterChar); if (propertyType.IsArray) { - var emptyExpression = new NewArrayExpression(elementType); + var emptyExpression = New.Array(elementType); var conditionalExpression = new TernaryConditionalExpression( isNullOrEmptyCheck, emptyExpression, splitResult); createArrayStatement = variableExpression.Assign(conditionalExpression).Terminate(); } else if (propertyType.IsList) { - var emptyExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType)); + var listType = New.List(elementType); var populatedExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), splitResult); var conditionalExpression = new TernaryConditionalExpression( - isNullOrEmptyCheck, emptyExpression, populatedExpression); + isNullOrEmptyCheck, listType, populatedExpression); createArrayStatement = variableExpression.Assign(conditionalExpression).Terminate(); } else { - var listExpression = New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), splitResult); + var initType = propertyType.PropertyInitializationType; + var listExpression = New.Instance(initType, splitResult); var conditionalExpression = new TernaryConditionalExpression( - isNullOrEmptyCheck, New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType)), listExpression); - createArrayStatement = variableExpression.Assign(New.Instance(propertyType, conditionalExpression)).Terminate(); + isNullOrEmptyCheck, New.Instance(initType), listExpression); + createArrayStatement = variableExpression.Assign(conditionalExpression).Terminate(); } } else if (elementType.IsEnum && !elementType.IsStruct && elementType.UnderlyingEnumType?.Equals(typeof(string)) == true) { var splitExpression = new TernaryConditionalExpression( isNullOrEmptyCheck, - new NewArrayExpression(typeof(string)), - stringValueVar.Invoke("Split", delimiterChar)); + New.Array(typeof(string)), + stringValueVar.As().Split(delimiterChar)); var s = new VariableExpression(typeof(string), "s"); - var trimmedS = s.Invoke("Trim"); + var trimmedS = s.Invoke(nameof(string.Trim)); var parseExpression = Static(elementType).Invoke("Parse", trimmedS); - var selectExpression = splitExpression.Invoke("Select", + var selectExpression = splitExpression.Invoke(nameof(Enumerable.Select), new FuncExpression([s.Declaration], parseExpression)); var finalExpression = propertyType.IsArray - ? selectExpression.Invoke("ToArray") + ? selectExpression.Invoke(nameof(Enumerable.ToArray)) : propertyType.IsList ? New.Instance(typeof(List<>).MakeGenericType(elementType.FrameworkType), selectExpression) - : New.Instance(propertyType, selectExpression); + : New.Instance(propertyType.PropertyInitializationType, selectExpression); createArrayStatement = variableExpression.Assign(finalExpression).Terminate(); } else { - throw new InvalidOperationException($"Encoded array deserialization is only supported for string and string enum arrays. Element type: {elementType.Name}"); + ScmCodeModelGenerator.Instance.Emitter.ReportDiagnostic( + DiagnosticCodes.UnsupportedSerialization, + $"Encoded array deserialization is only supported for string and string enum arrays. Element type: {elementType.Name}.", + severity: EmitterDiagnosticSeverity.Warning); + createArrayStatement = variableExpression.Assign(propertyType.IsList ? New.Instance(propertyType) : New.Array(elementType)).Terminate(); } return [ @@ -2445,13 +2451,5 @@ provider is ModelProvider modelProvider ? GetDeserializationMethodInvocationForType(modelProvider, jsonElementVariable, dataVariable, optionsVariable) : modelType.Deserialize(jsonElementVariable, null, optionsVariable); } - - private static bool IsArrayEncodingFormat(SerializationFormat format) - { - return format is SerializationFormat.Array_CommaDelimited or - SerializationFormat.Array_SpaceDelimited or - SerializationFormat.Array_PipeDelimited or - SerializationFormat.Array_NewlineDelimited; - } } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/Extensions/ArrayKnownEncodingExtensions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/Extensions/ArrayKnownEncodingExtensions.cs new file mode 100644 index 00000000000..5e7208fa199 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/Extensions/ArrayKnownEncodingExtensions.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Microsoft.TypeSpec.Generator.Input.Extensions +{ + public static class ArrayKnownEncodingExtensions + { + /// + /// Converts a string representation to ArrayKnownEncoding. + /// + public static bool TryParse(string? value, out ArrayKnownEncoding encoding) + { + encoding = default; + if (value == null) return false; + + return value switch + { + "ArrayEncoding.commaDelimited" or "commaDelimited" => + SetEncodingAndReturnTrue(out encoding, ArrayKnownEncoding.CommaDelimited), + "ArrayEncoding.spaceDelimited" or "spaceDelimited" => + SetEncodingAndReturnTrue(out encoding, ArrayKnownEncoding.SpaceDelimited), + "ArrayEncoding.pipeDelimited" or "pipeDelimited" => + SetEncodingAndReturnTrue(out encoding, ArrayKnownEncoding.PipeDelimited), + "ArrayEncoding.newlineDelimited" or "newlineDelimited" => + SetEncodingAndReturnTrue(out encoding, ArrayKnownEncoding.NewlineDelimited), + _ => false + }; + } + + /// + /// Converts ArrayKnownEncoding to SerializationFormat. + /// + public static SerializationFormat ToSerializationFormat(this ArrayKnownEncoding encoding) + { + return encoding switch + { + ArrayKnownEncoding.CommaDelimited => SerializationFormat.Array_CommaDelimited, + ArrayKnownEncoding.SpaceDelimited => SerializationFormat.Array_SpaceDelimited, + ArrayKnownEncoding.PipeDelimited => SerializationFormat.Array_PipeDelimited, + ArrayKnownEncoding.NewlineDelimited => SerializationFormat.Array_NewlineDelimited, + _ => throw new ArgumentOutOfRangeException(nameof(encoding), encoding, "Unknown array encoding") + }; + } + + /// + /// Gets the delimiter string for array serialization format. + /// + public static string GetDelimiter(SerializationFormat format) + { + return format switch + { + SerializationFormat.Array_CommaDelimited => ",", + SerializationFormat.Array_SpaceDelimited => " ", + SerializationFormat.Array_PipeDelimited => "|", + SerializationFormat.Array_NewlineDelimited => "\n", + _ => throw new ArgumentOutOfRangeException(nameof(format), format, "Unsupported array serialization format") + }; + } + + private static bool SetEncodingAndReturnTrue(out ArrayKnownEncoding encoding, ArrayKnownEncoding value) + { + encoding = value; + return true; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ArrayKnownEncoding.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ArrayKnownEncoding.cs new file mode 100644 index 00000000000..3b4100642ec --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ArrayKnownEncoding.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.TypeSpec.Generator.Input +{ + /// + /// Represents the known encoding formats for arrays. + /// + public enum ArrayKnownEncoding + { + /// + /// Comma-delimited array encoding + /// + CommaDelimited, + + /// + /// Space-delimited array encoding + /// + SpaceDelimited, + + /// + /// Pipe-delimited array encoding + /// + PipeDelimited, + + /// + /// Newline-delimited array encoding + /// + NewlineDelimited + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs index 719be7ed28e..52b0d256407 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using Microsoft.TypeSpec.Generator.Input.Extensions; + namespace Microsoft.TypeSpec.Generator.Input { public class InputModelProperty : InputProperty @@ -120,5 +122,14 @@ public void Update( SerializationOptions = serializationOptions; } } + + public ArrayKnownEncoding? GetArrayEncoding() + { + if (ArrayKnownEncodingExtensions.TryParse(Encode, out var encoding)) + { + return encoding; + } + return null; + } } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs index db2e2b559d4..e6fc8fa64fa 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs @@ -340,20 +340,15 @@ private SerializationFormat GetSerializationFormat(InputProperty inputProperty) { // Handle array encoding from InputModelProperty if (inputProperty is InputModelProperty modelProperty && - inputProperty.Type is InputArrayType && - !string.IsNullOrEmpty(modelProperty.Encode)) + inputProperty.Type is InputArrayType) { - return modelProperty.Encode switch + var arrayEncoding = modelProperty.GetArrayEncoding(); + if (arrayEncoding.HasValue) { - "commaDelimited" => SerializationFormat.Array_CommaDelimited, - "spaceDelimited" => SerializationFormat.Array_SpaceDelimited, - "pipeDelimited" => SerializationFormat.Array_PipeDelimited, - "newlineDelimited" => SerializationFormat.Array_NewlineDelimited, - _ => CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type) - }; + return arrayEncoding.Value.ToSerializationFormat(); + } } - // Use default serialization format logic return CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type); } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Snippets/StringSnippets.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Snippets/StringSnippets.cs index 50ac2f71ccf..af77b445581 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Snippets/StringSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Snippets/StringSnippets.cs @@ -21,9 +21,15 @@ public static ScopedApi Format(ScopedApi format, params ValueExp public static ScopedApi IsNullOrWhiteSpace(ScopedApi value, params ValueExpression[] args) => Static().Invoke(nameof(string.IsNullOrWhiteSpace), args.Prepend(value).ToArray()).As(); + public static ScopedApi IsNullOrEmpty(ScopedApi value) + => Static().Invoke(nameof(string.IsNullOrEmpty), [value]).As(); + public static ScopedApi Join(ValueExpression separator, ValueExpression values) => Static().Invoke(nameof(string.Join), [separator, values]).As(); + public static ValueExpression Split(this ScopedApi stringExpression, ValueExpression separator) + => stringExpression.Invoke(nameof(string.Split), [separator], null, false); + public static ScopedApi Substring(this ScopedApi stringExpression, ValueExpression startIndex) => stringExpression.Invoke(nameof(string.Substring), [startIndex], null, false).As();