Add nullable type converter to Interaction service (#1996)
* Add nullable type converter to Interaction service * update NullableConverter CanConvertTo body
This commit is contained in:
@@ -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)));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user