Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dpg): incorrect enum convenience/protocol parameter conversion #3898

Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ public static FormattableString GetConversionFormattable(this Parameter paramete
{
{ IsFrameworkType: false, Implementation: EnumType { IsExtensible: true } } when toType.EqualsIgnoreNullable(typeof(string)) => ".ToString()",
{ IsFrameworkType: false, Implementation: EnumType { IsExtensible: false } } when toType.EqualsIgnoreNullable(typeof(string)) => ".ToSerialString()",
{ IsFrameworkType: false, Implementation: EnumType } when toType.EqualsIgnoreNullable(typeof(int)) => ".ToSerialInt32()",
{ IsFrameworkType: false, Implementation: EnumType } when toType.EqualsIgnoreNullable(typeof(float)) => ".ToSerialSingle()",
{ IsFrameworkType: false, Implementation: ModelTypeProvider } when toType.EqualsIgnoreNullable(Configuration.ApiTypes.RequestContentType) => $".{Configuration.ApiTypes.ToRequestContentName}()",
_ => null
};
Expand Down
35 changes: 29 additions & 6 deletions test/TestProjects/Models-TypeSpec/Models-TypeSpec.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,14 @@ enum FixedIntEnum {
Four: 4
}

// @doc("Fixed float enum")
// enum FixedFloatEnum {
// One: 1.1,
// Two: 2.1,
// Four: 4.0
// }
@doc("Fixed float enum")
@fixed
@deprecated("should be replaced by cadl-ranch")
enum FixedFloatEnum {
One: 1.1,
Two: 2.1,
Four: 4.0
}

@doc("Extensible enum")
@deprecated("deprecated for test")
Expand All @@ -119,6 +121,15 @@ enum ExtensibleEnum {
Four: "4"
}

@doc("Extensible int enum")
@deprecated("should be replaced by cadl-ranch")
enum ExtensibleIntEnum {
One: 1,
Two: 2,
Four: 4
}


@doc("Model used both as input and output")
model RoundTripModel extends BaseModel {
@doc("Required string, illustrating a reference type property.")
Expand Down Expand Up @@ -597,6 +608,18 @@ op roundTripRecursive(@body input: RoundTripRecursiveModel): RoundTripRecursiveM
@convenientAPI(true)
op selfReference(): ErrorModel;

@route("/fixedFloatEnum")
@doc("Returns model that has property of its own type")
@get
@convenientAPI(true)
op fixedFloatEnum(@query input: FixedFloatEnum): OutputModel;

@route("/extenisbleIntEnum")
@doc("Returns model that has property of its own type")
@get
@convenientAPI(true)
op extenisbleIntEnum(@query input: ExtensibleIntEnum): OutputModel;

@doc("Base model")
model NoUseBase {
@doc("base model property")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,174 @@ Response response = client.SelfReference(null);
JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("message").ToString());
Console.WriteLine(result.GetProperty("innerError").GetProperty("message").ToString());
]]></code></example>
</member>
<member name="FixedFloatEnumAsync(FixedFloatEnum,CancellationToken)">
<example>
This sample shows how to call FixedFloatEnumAsync.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = await client.FixedFloatEnumAsync(FixedFloatEnum.One);
]]></code>
This sample shows how to call FixedFloatEnumAsync with all parameters.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = await client.FixedFloatEnumAsync(FixedFloatEnum.One);
]]></code></example>
</member>
<member name="FixedFloatEnum(FixedFloatEnum,CancellationToken)">
<example>
This sample shows how to call FixedFloatEnum.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = client.FixedFloatEnum(FixedFloatEnum.One);
]]></code>
This sample shows how to call FixedFloatEnum with all parameters.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = client.FixedFloatEnum(FixedFloatEnum.One);
]]></code></example>
</member>
<member name="FixedFloatEnumAsync(float,RequestContext)">
<example>
This sample shows how to call FixedFloatEnumAsync and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = await client.FixedFloatEnumAsync(1.1F);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code>
This sample shows how to call FixedFloatEnumAsync with all parameters and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = await client.FixedFloatEnumAsync(1.1F);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code></example>
</member>
<member name="FixedFloatEnum(float,RequestContext)">
<example>
This sample shows how to call FixedFloatEnum and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = client.FixedFloatEnum(1.1F);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code>
This sample shows how to call FixedFloatEnum with all parameters and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = client.FixedFloatEnum(1.1F);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code></example>
</member>
<member name="ExtenisbleIntEnumAsync(ExtensibleIntEnum,CancellationToken)">
<example>
This sample shows how to call ExtenisbleIntEnumAsync.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = await client.ExtenisbleIntEnumAsync(ExtensibleIntEnum.One);
]]></code>
This sample shows how to call ExtenisbleIntEnumAsync with all parameters.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = await client.ExtenisbleIntEnumAsync(ExtensibleIntEnum.One);
]]></code></example>
</member>
<member name="ExtenisbleIntEnum(ExtensibleIntEnum,CancellationToken)">
<example>
This sample shows how to call ExtenisbleIntEnum.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = client.ExtenisbleIntEnum(ExtensibleIntEnum.One);
]]></code>
This sample shows how to call ExtenisbleIntEnum with all parameters.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response<OutputModel> response = client.ExtenisbleIntEnum(ExtensibleIntEnum.One);
]]></code></example>
</member>
<member name="ExtenisbleIntEnumAsync(int,RequestContext)">
<example>
This sample shows how to call ExtenisbleIntEnumAsync and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = await client.ExtenisbleIntEnumAsync(1);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code>
This sample shows how to call ExtenisbleIntEnumAsync with all parameters and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = await client.ExtenisbleIntEnumAsync(1);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code></example>
</member>
<member name="ExtenisbleIntEnum(int,RequestContext)">
<example>
This sample shows how to call ExtenisbleIntEnum and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = client.ExtenisbleIntEnum(1);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code>
This sample shows how to call ExtenisbleIntEnum with all parameters and parse the result.
<code><![CDATA[
Uri endpoint = new Uri("<https://my-service.azure.com>");
ModelsTypeSpecClient client = new ModelsTypeSpecClient(endpoint);

Response response = client.ExtenisbleIntEnum(1);

JsonElement result = JsonDocument.Parse(response.ContentStream).RootElement;
Console.WriteLine(result.GetProperty("requiredString").ToString());
Console.WriteLine(result.GetProperty("requiredInt").ToString());
]]></code></example>
</member>
<member name="RoundTripToOutputWithNoUseBaseAsync(RoundTripOnNoUse,CancellationToken)">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;
using System.ComponentModel;
using System.Globalization;

namespace ModelsTypeSpec.Models
{
/// <summary> Extensible int enum. </summary>
[Obsolete("should be replaced by cadl-ranch")]
public readonly partial struct ExtensibleIntEnum : IEquatable<ExtensibleIntEnum>
{
private readonly int _value;

/// <summary> Initializes a new instance of <see cref="ExtensibleIntEnum"/>. </summary>
public ExtensibleIntEnum(int value)
{
_value = value;
}

private const int OneValue = 1;
private const int TwoValue = 2;
private const int FourValue = 4;

/// <summary> 1. </summary>
public static ExtensibleIntEnum One { get; } = new ExtensibleIntEnum(OneValue);
/// <summary> 2. </summary>
public static ExtensibleIntEnum Two { get; } = new ExtensibleIntEnum(TwoValue);
/// <summary> 4. </summary>
public static ExtensibleIntEnum Four { get; } = new ExtensibleIntEnum(FourValue);

internal int ToSerialInt32() => _value;

/// <summary> Determines if two <see cref="ExtensibleIntEnum"/> values are the same. </summary>
public static bool operator ==(ExtensibleIntEnum left, ExtensibleIntEnum right) => left.Equals(right);
/// <summary> Determines if two <see cref="ExtensibleIntEnum"/> values are not the same. </summary>
public static bool operator !=(ExtensibleIntEnum left, ExtensibleIntEnum right) => !left.Equals(right);
/// <summary> Converts a string to a <see cref="ExtensibleIntEnum"/>. </summary>
public static implicit operator ExtensibleIntEnum(int value) => new ExtensibleIntEnum(value);

/// <inheritdoc />
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is ExtensibleIntEnum other && Equals(other);
/// <inheritdoc />
public bool Equals(ExtensibleIntEnum other) => Equals(_value, other._value);

/// <inheritdoc />
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => _value.GetHashCode();
/// <inheritdoc />
public override string ToString() => _value.ToString(CultureInfo.InvariantCulture);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;

namespace ModelsTypeSpec.Models
{
internal static partial class FixedFloatEnumExtensions
{
public static float ToSerialSingle(this FixedFloatEnum value) => value switch
{
FixedFloatEnum.One => 1.1F,
FixedFloatEnum.Two => 2.1F,
FixedFloatEnum.Four => 4F,
_ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown FixedFloatEnum value.")
};

public static FixedFloatEnum ToFixedFloatEnum(this float value)
{
if (value == 1.1F) return FixedFloatEnum.One;
if (value == 2.1F) return FixedFloatEnum.Two;
if (value == 4F) return FixedFloatEnum.Four;
throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown FixedFloatEnum value.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;

namespace ModelsTypeSpec.Models
{
/// <summary> Fixed float enum. </summary>
[Obsolete("should be replaced by cadl-ranch")]
public enum FixedFloatEnum
{
/// <summary> 1.1. </summary>
One,
/// <summary> 2.1. </summary>
Two,
/// <summary> 4. </summary>
Four
}
}
Loading