-
-
Notifications
You must be signed in to change notification settings - Fork 749
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
Allow flag enums to have a custom prefix by making the naming function virtual #7463
Conversation
…n virtual Currently in order to do this, the entire file needs to be copied to modify this one static function. Simple making it virtual allows a child class to override it instead.
Also, I'm just now realizing that the implementation uses internal classes like |
The class itself should be internal sealed. |
I am closing this PR |
are you just trying to change the name? if so you can chain another interceptor in that will rename it ... |
If your on slack.chillicream.com ... put a question on general on how to prefix flags arrays and I will post some code. |
Was able to achieve it with a type interceptor: using System;
using System.Collections.Generic;
using HotChocolate.Configuration;
using HotChocolate.Types.Descriptors.Definitions;
using Tgstation.Server.Api.Rights;
namespace Tgstation.Server.Host.GraphQL.Types.Interceptors
{
/// <summary>
/// Fixes the names used for the default flags types in API rights.
/// </summary>
sealed class RightsTypeInterceptor : TypeInterceptor
{
/// <summary>
/// Names of rights GraphQL object types.
/// </summary>
private readonly HashSet<string> objectNames;
/// <summary>
/// Names of rights GraphQL input types.
/// </summary>
private readonly HashSet<string> inputNames;
/// <summary>
/// Initializes a new instance of the <see cref="RightsTypeInterceptor"/> class.
/// </summary>
public RightsTypeInterceptor()
{
objectNames = new HashSet<string>();
inputNames = new HashSet<string>();
foreach (var rightType in Enum.GetValues<RightsType>())
{
var flagName = $"{rightType}RightsFlags";
objectNames.Add(flagName);
inputNames.Add($"{flagName}Input");
}
}
/// <summary>
/// Fix the "is" prefix on a given set of <paramref name="fields"/>.
/// </summary>
/// <typeparam name="TField">The <see cref="Type"/> of <see cref="FieldDefinitionBase"/> to correct.</typeparam>
/// <param name="fields">The <see cref="IBindableList{T}"/> of <typeparamref name="TField"/>s to operate on.</param>
static void FixFields<TField>(IBindableList<TField> fields)
where TField : FieldDefinitionBase
{
TField? noneField = null;
const string NoneFieldName = "isNone";
foreach (var field in fields)
{
var fieldName = field.Name;
if (fieldName == NoneFieldName)
{
noneField = field;
continue;
}
const string IsPrefix = "is";
if (!fieldName.StartsWith(IsPrefix))
throw new InvalidOperationException("Expected flags enum type field to start with \"is\"!");
field.Name = $"can{fieldName.Substring(IsPrefix.Length)}";
}
if (noneField == null)
throw new InvalidOperationException($"Expected flags enum type field to contain \"{NoneFieldName}\"!");
fields.Remove(noneField);
}
/// <inheritdoc />
public override void OnBeforeRegisterDependencies(ITypeDiscoveryContext discoveryContext, DefinitionBase definition)
{
ArgumentNullException.ThrowIfNull(definition);
if (definition is ObjectTypeDefinition objectTypeDef)
{
if (objectNames.Contains(objectTypeDef.Name))
FixFields(objectTypeDef.Fields);
}
else if (definition is InputObjectTypeDefinition inputTypeDef)
if (inputNames.Contains(inputTypeDef.Name))
FixFields(inputTypeDef.Fields);
}
}
} |
Currently in order to do this, the entire file needs to be copied to modify this one static function. Simple making it virtual allows a child class to override it instead.