Browse Source

Add nullable type converter to Interaction service

pull/1996/head
quin lynch 3 years ago
parent
commit
dfabbcb0f5
2 changed files with 39 additions and 3 deletions
  1. +7
    -3
      src/Discord.Net.Interactions/InteractionService.cs
  2. +32
    -0
      src/Discord.Net.Interactions/TypeConverters/NullableConverter.cs

+ 7
- 3
src/Discord.Net.Interactions/InteractionService.cs View File

@@ -165,7 +165,8 @@ namespace Discord.Interactions
[typeof(IUser)] = typeof(DefaultUserConverter<>),
[typeof(IMentionable)] = typeof(DefaultMentionableConverter<>),
[typeof(IConvertible)] = typeof(DefaultValueConverter<>),
[typeof(Enum)] = typeof(EnumConverter<>)
[typeof(Enum)] = typeof(EnumConverter<>),
[typeof(Nullable<>)] = typeof(NullableConverter<>),
};

_typeConverters = new ConcurrentDictionary<Type, TypeConverter>
@@ -692,8 +693,8 @@ namespace Discord.Interactions
{
if (_typeConverters.TryGetValue(type, out var specific))
return specific;
else if (_genericTypeConverters.Any(x => x.Key.IsAssignableFrom(type)))
else if (_genericTypeConverters.Any(x => x.Key.IsAssignableFrom(type)
|| (x.Key.IsGenericTypeDefinition && type.IsGenericType && x.Key.GetGenericTypeDefinition() == type.GetGenericTypeDefinition())))
{
services ??= EmptyServiceProvider.Instance;

@@ -926,6 +927,9 @@ namespace Discord.Interactions
if (_genericTypeConverters.TryGetValue(type, out var matching))
return matching;

if (type.IsGenericType && _genericTypeConverters.TryGetValue(type.GetGenericTypeDefinition(), out var genericDefinition))
return genericDefinition;

var typeInterfaces = type.GetInterfaces();
var candidates = _genericTypeConverters.Where(x => x.Key.IsAssignableFrom(type))
.OrderByDescending(x => typeInterfaces.Count(y => y.IsAssignableFrom(x.Key)));


+ 32
- 0
src/Discord.Net.Interactions/TypeConverters/NullableConverter.cs View File

@@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;

namespace Discord.Interactions
{
internal class NullableConverter<T> : TypeConverter
{
private readonly TypeConverter _typeConverter;

public NullableConverter(InteractionService interactionService, IServiceProvider services)
{
var type = Nullable.GetUnderlyingType(typeof(T));

if (type is null)
throw new ArgumentException($"No type {nameof(TypeConverter)} is defined for this {type.FullName}", "type");

_typeConverter = interactionService.GetTypeConverter(type, services);
}

public override bool CanConvertTo(Type type)
=> Nullable.GetUnderlyingType(type) != null;

public override ApplicationCommandOptionType GetDiscordType()
=> _typeConverter.GetDiscordType();

public override Task<TypeConverterResult> ReadAsync(IInteractionContext context, IApplicationCommandInteractionDataOption option, IServiceProvider services)
=> _typeConverter.ReadAsync(context, option, services);

public override void Write(ApplicationCommandOptionProperties properties, IParameterInfo parameter)
=> _typeConverter.Write(properties, parameter);
}
}

Loading…
Cancel
Save