Skip to content

Commit 5871016

Browse files
Use Azure.Core ResponseError type for errors (Azure#49817)
* Use Azure.Core ResponseError type for errors * PR fb
1 parent 5aa6916 commit 5871016

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

eng/packages/http-client-csharp/generator/Azure.Generator/src/AzureTypeFactory.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.ClientModel.Primitives;
1717
using System.Collections.Generic;
1818
using System.Text.Json;
19+
using Microsoft.TypeSpec.Generator.Providers;
1920

2021
namespace Azure.Generator
2122
{
@@ -65,6 +66,14 @@ public class AzureTypeFactory : ScmTypeFactory
6566
return result;
6667
}
6768
}
69+
else if (inputType is InputModelType inputModelType)
70+
{
71+
if (KnownAzureTypes.TryGetKnownType(inputModelType.CrossLanguageDefinitionId, out var knownType))
72+
{
73+
return knownType;
74+
}
75+
}
76+
6877
return base.CreateCSharpTypeCore(inputType);
6978
}
7079

@@ -73,7 +82,7 @@ public class AzureTypeFactory : ScmTypeFactory
7382
InputPrimitiveType? primitiveType = inputType;
7483
while (primitiveType != null)
7584
{
76-
if (KnownAzureTypes.TryGetPrimitiveType(primitiveType.CrossLanguageDefinitionId, out var knownType))
85+
if (KnownAzureTypes.TryGetKnownType(primitiveType.CrossLanguageDefinitionId, out var knownType))
7786
{
7887
return knownType;
7988
}
@@ -84,6 +93,17 @@ public class AzureTypeFactory : ScmTypeFactory
8493
return null;
8594
}
8695

96+
/// <inheritdoc/>
97+
protected override IReadOnlyList<TypeProvider> CreateSerializationsCore(InputType inputType, TypeProvider typeProvider)
98+
{
99+
if (KnownAzureTypes.IsModelTypeWithoutSerialization(typeProvider.Type))
100+
{
101+
return [];
102+
}
103+
104+
return base.CreateSerializationsCore(inputType, typeProvider);
105+
}
106+
87107
/// <inheritdoc/>
88108
#pragma warning disable AZC0014 // Avoid using banned types in public API
89109
public override ValueExpression DeserializeJsonValue(Type valueType, ScopedApi<JsonElement> element, SerializationFormat format)

eng/packages/http-client-csharp/generator/Azure.Generator/src/Primitives/KnownAzureTypes.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ internal static class KnownAzureTypes
2929
private const string ETagId = "Azure.Core.eTag";
3030
private const string AzureLocationId = "Azure.Core.azureLocation";
3131
private const string ArmIdId = "Azure.Core.armResourceIdentifier";
32+
private const string AzureError = "Azure.Core.Foundations.Error";
3233

3334
private static MethodBodyStatement SerializeTypeWithImplicitOperatorToString(ValueExpression value, ScopedApi<Utf8JsonWriter> writer, ScopedApi<ModelReaderWriterOptions> options, SerializationFormat format)
3435
=> writer.WriteStringValue(value);
@@ -42,6 +43,14 @@ private static MethodBodyStatement SerializeTypeWithToString(ValueExpression val
4243
private static ValueExpression DeserializeParsableStringLikeType(CSharpType valueType, ScopedApi<JsonElement> element, SerializationFormat format)
4344
=> Static(valueType).Invoke("Parse", element.GetString());
4445

46+
private static MethodBodyStatement SerializeResponseError(ValueExpression value, ScopedApi<Utf8JsonWriter> writer, ScopedApi<ModelReaderWriterOptions> options, SerializationFormat format)
47+
=> Static(typeof(JsonSerializer)).Invoke(nameof(JsonSerializer.Serialize), writer, value).Terminate();
48+
49+
private static ValueExpression DeserializeResponseError(CSharpType valueType,
50+
ScopedApi<JsonElement> element,
51+
SerializationFormat format)
52+
=> Static(typeof(JsonSerializer)).Invoke(nameof(JsonSerializer.Deserialize), arguments: [element.GetRawText()], typeArguments: [valueType], callAsAsync: false);
53+
4554
private static readonly IReadOnlyDictionary<string, CSharpType> _idToTypes = new Dictionary<string, CSharpType>
4655
{
4756
[UuidId] = typeof(Guid),
@@ -50,6 +59,7 @@ private static ValueExpression DeserializeParsableStringLikeType(CSharpType valu
5059
[ETagId] = typeof(ETag),
5160
[AzureLocationId] = typeof(AzureLocation),
5261
[ArmIdId] = typeof(ResourceIdentifier),
62+
[AzureError] = typeof(ResponseError),
5363
};
5464

5565
private static readonly IReadOnlyDictionary<Type, SerializationExpression> _typeToSerializationExpression = new Dictionary<Type, SerializationExpression>
@@ -59,6 +69,7 @@ private static ValueExpression DeserializeParsableStringLikeType(CSharpType valu
5969
[typeof(ETag)] = SerializeTypeWithToString,
6070
[typeof(AzureLocation)] = SerializeTypeWithImplicitOperatorToString,
6171
[typeof(ResourceIdentifier)] = SerializeTypeWithImplicitOperatorToString,
72+
[typeof(ResponseError)] = SerializeResponseError,
6273
};
6374

6475
private static readonly IReadOnlyDictionary<Type, DeserializationExpression> _typeToDeserializationExpression = new Dictionary<Type, DeserializationExpression>
@@ -68,9 +79,20 @@ private static ValueExpression DeserializeParsableStringLikeType(CSharpType valu
6879
[typeof(ETag)] = DeserializeNewInstanceStringLikeType,
6980
[typeof(AzureLocation)] = DeserializeNewInstanceStringLikeType,
7081
[typeof(ResourceIdentifier)] = DeserializeNewInstanceStringLikeType,
82+
[typeof(ResponseError)] = DeserializeResponseError,
7183
};
7284

73-
public static bool TryGetPrimitiveType(string id, [MaybeNullWhen(false)] out CSharpType type) => _idToTypes.TryGetValue(id, out type);
85+
public static bool IsModelTypeWithoutSerialization(CSharpType type)
86+
{
87+
if (type.Equals(typeof(ResponseError)))
88+
{
89+
return true;
90+
}
91+
92+
return false;
93+
}
94+
95+
public static bool TryGetKnownType(string id, [MaybeNullWhen(false)] out CSharpType type) => _idToTypes.TryGetValue(id, out type);
7496

7597
public static bool TryGetJsonSerializationExpression(Type type, [MaybeNullWhen(false)] out SerializationExpression expression) => _typeToSerializationExpression.TryGetValue(type, out expression);
7698

eng/packages/http-client-csharp/generator/Azure.Generator/test/AzureTypeFactoryTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public void SetUp()
2828
[TestCase(typeof(ETag), ExpectedResult = "writer.WriteStringValue(value.ToString());\n")]
2929
[TestCase(typeof(AzureLocation), ExpectedResult = "writer.WriteStringValue(value);\n")]
3030
[TestCase(typeof(ResourceIdentifier), ExpectedResult = "writer.WriteStringValue(value);\n")]
31+
[TestCase(typeof(ResponseError), ExpectedResult = "global::System.Text.Json.JsonSerializer.Serialize(writer, value);\n")]
3132
public string ValidateSerializationStatement(Type type)
3233
{
3334
var value = new ParameterProvider("value", $"", type).AsExpression().As(type);
@@ -45,6 +46,7 @@ public string ValidateSerializationStatement(Type type)
4546
[TestCase(typeof(ETag), ExpectedResult = "new global::Azure.ETag(element.GetString())")]
4647
[TestCase(typeof(AzureLocation), ExpectedResult = "new global::Azure.Core.AzureLocation(element.GetString())")]
4748
[TestCase(typeof(ResourceIdentifier), ExpectedResult = "new global::Azure.Core.ResourceIdentifier(element.GetString())")]
49+
[TestCase(typeof(ResponseError), ExpectedResult = "global::System.Text.Json.JsonSerializer.Deserialize<global::Azure.ResponseError>(element.GetRawText())")]
4850
public string ValidateDeserializationExpression(Type type)
4951
{
5052
var element = new ParameterProvider("element", $"", typeof(JsonElement)).AsExpression().As<JsonElement>();
@@ -126,5 +128,17 @@ public void ResourceIdentifier()
126128
Assert.IsTrue(actual?.IsFrameworkType);
127129
Assert.AreEqual(typeof(ResourceIdentifier), actual?.FrameworkType);
128130
}
131+
132+
[Test]
133+
public void ResponseError()
134+
{
135+
var input = InputFactory.Primitive.String("responseError", "Azure.Core.Foundations.Error");
136+
137+
var actual = AzureClientGenerator.Instance.TypeFactory.CreateCSharpType(input);
138+
139+
Assert.IsNotNull(actual);
140+
Assert.IsTrue(actual?.IsFrameworkType);
141+
Assert.AreEqual(typeof(ResponseError), actual?.FrameworkType);
142+
}
129143
}
130144
}

0 commit comments

Comments
 (0)