diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index f526e8f3b..00262410a 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -57,7 +57,11 @@ namespace Discord.Commands _defaultTypeReaders = new ConcurrentDictionary(); foreach (var type in PrimitiveParsers.SupportedTypes) + { _defaultTypeReaders[type] = PrimitiveTypeReader.Create(type); + if (type.GetTypeInfo().IsValueType) + _defaultTypeReaders[typeof(Nullable<>).MakeGenericType(type)] = NullableTypeReader.Create(type); + } var entityTypeReaders = ImmutableList.CreateBuilder>(); entityTypeReaders.Add(new Tuple(typeof(IMessage), typeof(MessageTypeReader<>))); diff --git a/src/Discord.Net.Commands/Readers/NullableTypeReader.cs b/src/Discord.Net.Commands/Readers/NullableTypeReader.cs new file mode 100644 index 000000000..1a8e21e47 --- /dev/null +++ b/src/Discord.Net.Commands/Readers/NullableTypeReader.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + internal static class NullableTypeReader + { + public static TypeReader Create(Type type) + { + type = typeof(NullableTypeReader<>).MakeGenericType(type); + return Activator.CreateInstance(type) as TypeReader; + } + } + + internal class NullableTypeReader : TypeReader + where T : struct + { + private readonly TryParseDelegate _tryParse; + + public NullableTypeReader() + { + _tryParse = PrimitiveParsers.Get(); + } + + public override Task Read(ICommandContext context, string input) + { + if(input == null) + return Task.FromResult(TypeReaderResult.FromSuccess(new Nullable())); + T value; + if (_tryParse(input, out value)) + return Task.FromResult(TypeReaderResult.FromSuccess(new Nullable(value))); + return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Failed to parse {typeof(T).Name}")); + } + } +}