Skip to content

Commit

Permalink
Properly get attributes.
Browse files Browse the repository at this point in the history
Remove EnumMember. STJ doesn't actually use this.
Add a unit test.
Test in .NET 9. Unsure if author wants to test both 8 and 9.
  • Loading branch information
wasabii committed Jan 5, 2025
1 parent 6563858 commit ecdb22d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
25 changes: 13 additions & 12 deletions src/KubeOps.Transpiler/Crds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,35 +345,36 @@ private static V1JSONSchemaProps Map(this MetadataLoadContext context, Type type

private static IList<object> GetEnumNames(this MetadataLoadContext context, Type type)
{
#if NET9_0_OR_GREATER
var attributeNameByFieldName = new Dictionary<string, string>();

foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (field.GetCustomAttribute<EnumMemberAttribute>() is { Value: not null } enumMemberAtribute)
{
attributeNameByFieldName.Add(field.Name, enumMemberAtribute.Value);
}
#if NET9_0_OR_GREATER
if (field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>() is { Name: not null } jsonMemberNameAtribute)
if (field.GetCustomAttributeData<JsonStringEnumMemberNameAttribute>() is { } jsonMemberNameAttribute &&
jsonMemberNameAttribute.GetCustomAttributeCtorArg<string>(context, 0) is { } jsonMemberNameAtributeName)
{
attributeNameByFieldName.Add(field.Name, jsonMemberNameAtribute.Name);
attributeNameByFieldName.Add(field.Name, jsonMemberNameAtributeName);
}
#endif
}

var enumName = new List<object>();
var enumNames = new List<object>();

foreach (var value in Enum.GetNames(type))
{
if (attributeNameByFieldName.TryGetValue(value, out var name))
{
enumName.Add(name);
enumNames.Add(name);
}
else
{
enumName.Add(value);
enumNames.Add(value);
}
}

return enumName;
return enumNames;
#else
return Enum.GetNames(type);
#endif
}

private static V1JSONSchemaProps MapObjectType(this MetadataLoadContext context, Type type)
Expand Down
12 changes: 12 additions & 0 deletions src/KubeOps.Transpiler/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ public static class Utilities
.GetCustomAttributes(type)
.FirstOrDefault(a => a.AttributeType.Name == typeof(TAttribute).Name);

/// <summary>
/// Load a custom attribute from a read-only-reflected field.
/// </summary>
/// <param name="field">The field.</param>
/// <typeparam name="TAttribute">The type of the attribute to load.</typeparam>
/// <returns>The custom attribute data if an attribute is found.</returns>
public static CustomAttributeData? GetCustomAttributeData<TAttribute>(this FieldInfo field)
where TAttribute : Attribute
=> CustomAttributeData
.GetCustomAttributes(field)
.FirstOrDefault(a => a.AttributeType.Name == typeof(TAttribute).Name);

/// <summary>
/// Load a custom attribute from a read-only-reflected property.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion test/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand Down
23 changes: 23 additions & 0 deletions test/KubeOps.Transpiler.Test/Crds.Mlc.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class CrdsMlcTest(MlcProvider provider) : TranspilerTestBase(provider)
[InlineData(typeof(SetIntEntity), "array", null, false)]
[InlineData(typeof(InheritedEnumerableEntity), "array", null, false)]
[InlineData(typeof(EnumEntity), "string", null, false)]
[InlineData(typeof(NamedEnumEntity), "string", null, false)]
[InlineData(typeof(NullableEnumEntity), "string", null, true)]
[InlineData(typeof(DictionaryEntity), "object", null, false)]
[InlineData(typeof(EnumerableKeyPairsEntity), "object", null, false)]
Expand Down Expand Up @@ -475,6 +476,14 @@ public void Should_Correctly_Use_Entity_Scope_Attribute()
clusterCrd.Spec.Scope.Should().Be("Cluster");
}

[Fact]
public void Should_Correctly_Get_Enum_Value_From_JsonStringEnumMemberNameAttribute()
{
var crd = _mlc.Transpile(typeof(NamedEnumEntity));
var specProperties = crd.Spec.Versions.First().Schema.OpenAPIV3Schema.Properties["property"];
specProperties.EnumProperty.Should().BeEquivalentTo(["enumValue1", "enumValue2"]);
}

#region Test Entity Classes

[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
Expand Down Expand Up @@ -659,6 +668,20 @@ public enum TestSpecEnum
}
}

[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
private class NamedEnumEntity : CustomKubernetesEntity
{
public TestSpecEnum Property { get; set; }

public enum TestSpecEnum
{
[JsonStringEnumMemberName("enumValue1")]
Value1,
[JsonStringEnumMemberName("enumValue2")]
Value2,
}
}

[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
private class SimpleDictionaryEntity : CustomKubernetesEntity
{
Expand Down

0 comments on commit ecdb22d

Please sign in to comment.