Add nullable type converter to Interaction service (#1996)

* Add nullable type converter to Interaction service

* update NullableConverter CanConvertTo body
This commit is contained in:
Quin Lynch
2021-12-24 10:37:57 -04:00
committed by GitHub
parent cb1aad308b
commit ccc365edfd
2 changed files with 36 additions and 3 deletions

View File

@@ -166,7 +166,8 @@ namespace Discord.Interactions
[typeof(IUser)] = typeof(DefaultUserConverter<>), [typeof(IUser)] = typeof(DefaultUserConverter<>),
[typeof(IMentionable)] = typeof(DefaultMentionableConverter<>), [typeof(IMentionable)] = typeof(DefaultMentionableConverter<>),
[typeof(IConvertible)] = typeof(DefaultValueConverter<>), [typeof(IConvertible)] = typeof(DefaultValueConverter<>),
[typeof(Enum)] = typeof(EnumConverter<>) [typeof(Enum)] = typeof(EnumConverter<>),
[typeof(Nullable<>)] = typeof(NullableConverter<>),
}; };
_typeConverters = new ConcurrentDictionary<Type, TypeConverter> _typeConverters = new ConcurrentDictionary<Type, TypeConverter>
@@ -693,8 +694,8 @@ namespace Discord.Interactions
{ {
if (_typeConverters.TryGetValue(type, out var specific)) if (_typeConverters.TryGetValue(type, out var specific))
return 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; services ??= EmptyServiceProvider.Instance;
@@ -927,6 +928,9 @@ namespace Discord.Interactions
if (_genericTypeConverters.TryGetValue(type, out var matching)) if (_genericTypeConverters.TryGetValue(type, out var matching))
return matching; return matching;
if (type.IsGenericType && _genericTypeConverters.TryGetValue(type.GetGenericTypeDefinition(), out var genericDefinition))
return genericDefinition;
var typeInterfaces = type.GetInterfaces(); var typeInterfaces = type.GetInterfaces();
var candidates = _genericTypeConverters.Where(x => x.Key.IsAssignableFrom(type)) var candidates = _genericTypeConverters.Where(x => x.Key.IsAssignableFrom(type))
.OrderByDescending(x => typeInterfaces.Count(y => y.IsAssignableFrom(x.Key))); .OrderByDescending(x => typeInterfaces.Count(y => y.IsAssignableFrom(x.Key)));

View File

@@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;
namespace Discord.Interactions
{
internal class NullableConverter<T> : TypeConverter<T>
{
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 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);
}
}