@@ -1,6 +1,7 @@ | |||||
using System; | using System; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | |||||
using System.Reflection; | using System.Reflection; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
@@ -245,7 +246,7 @@ namespace Discord.Commands | |||||
builder.Summary = summary.Text; | builder.Summary = summary.Text; | ||||
break; | break; | ||||
case OverrideTypeReaderAttribute typeReader: | case OverrideTypeReaderAttribute typeReader: | ||||
builder.TypeReader = GetTypeReader(service, paramType, typeReader.TypeReader); | |||||
builder.TypeReaders = ImmutableList.Create(GetTypeReader(service, paramType, typeReader.TypeReader)); | |||||
break; | break; | ||||
case ParamArrayAttribute _: | case ParamArrayAttribute _: | ||||
builder.IsMultiple = true; | builder.IsMultiple = true; | ||||
@@ -271,17 +272,9 @@ namespace Discord.Commands | |||||
builder.ParameterType = paramType; | builder.ParameterType = paramType; | ||||
if (builder.TypeReader == null) | |||||
if (builder.TypeReaders == null || builder.TypeReaders.Count == 0) | |||||
{ | { | ||||
var readers = service.GetTypeReaders(paramType); | |||||
TypeReader reader = null; | |||||
if (readers != null) | |||||
reader = readers.FirstOrDefault().Value; | |||||
else | |||||
reader = service.GetDefaultTypeReader(paramType); | |||||
builder.TypeReader = reader; | |||||
builder.TypeReaders = service.GetTypeReaders(paramType).Values.ToImmutableList(); | |||||
} | } | ||||
} | } | ||||
@@ -1,8 +1,9 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Reflection; | using System.Reflection; | ||||
using System.Collections.Generic; | |||||
namespace Discord.Commands.Builders | namespace Discord.Commands.Builders | ||||
{ | { | ||||
@@ -15,7 +16,7 @@ namespace Discord.Commands.Builders | |||||
public string Name { get; internal set; } | public string Name { get; internal set; } | ||||
public Type ParameterType { get; internal set; } | public Type ParameterType { get; internal set; } | ||||
public TypeReader TypeReader { get; set; } | |||||
public IReadOnlyCollection<TypeReader> TypeReaders { get; set; } | |||||
public bool IsOptional { get; set; } | public bool IsOptional { get; set; } | ||||
public bool IsRemainder { get; set; } | public bool IsRemainder { get; set; } | ||||
public bool IsMultiple { get; set; } | public bool IsMultiple { get; set; } | ||||
@@ -45,13 +46,13 @@ namespace Discord.Commands.Builders | |||||
internal void SetType(Type type) | internal void SetType(Type type) | ||||
{ | { | ||||
var readers = Command.Module.Service.GetTypeReaders(type); | |||||
if (readers != null) | |||||
TypeReader = readers.FirstOrDefault().Value; | |||||
var readers = Command.Module.Service.GetTypeReaders(type).Values.ToImmutableList(); | |||||
if (readers.Count > 1) | |||||
TypeReaders = readers; | |||||
else | else | ||||
TypeReader = Command.Module.Service.GetDefaultTypeReader(type); | |||||
TypeReaders = ImmutableList.Create(Command.Module.Service.GetDefaultTypeReader(type)); | |||||
if (TypeReader == null) | |||||
if (TypeReaders.Count == 0) | |||||
throw new InvalidOperationException($"{type} does not have a TypeReader registered for it. Parameter: {Name} in {Command.PrimaryAlias}"); | throw new InvalidOperationException($"{type} does not have a TypeReader registered for it. Parameter: {Name} in {Command.PrimaryAlias}"); | ||||
if (type.GetTypeInfo().IsValueType) | if (type.GetTypeInfo().IsValueType) | ||||
@@ -100,10 +101,10 @@ namespace Discord.Commands.Builders | |||||
internal ParameterInfo Build(CommandInfo info) | internal ParameterInfo Build(CommandInfo info) | ||||
{ | { | ||||
if (TypeReader == null) | |||||
if (TypeReaders == null || TypeReaders.Count == 0) | |||||
throw new InvalidOperationException($"No type reader found for type {ParameterType.Name}, one must be specified"); | throw new InvalidOperationException($"No type reader found for type {ParameterType.Name}, one must be specified"); | ||||
return new ParameterInfo(this, info, Command.Module.Service); | return new ParameterInfo(this, info, Command.Module.Service); | ||||
} | } | ||||
} | } | ||||
} | |||||
} |
@@ -1,15 +1,15 @@ | |||||
using Discord.Commands.Builders; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using Discord.Commands.Builders; | |||||
namespace Discord.Commands | namespace Discord.Commands | ||||
{ | { | ||||
public class ParameterInfo | public class ParameterInfo | ||||
{ | { | ||||
private readonly TypeReader _reader; | |||||
private readonly IReadOnlyCollection<TypeReader> _readers; | |||||
public CommandInfo Command { get; } | public CommandInfo Command { get; } | ||||
public string Name { get; } | public string Name { get; } | ||||
@@ -39,7 +39,7 @@ namespace Discord.Commands | |||||
Preconditions = builder.Preconditions.ToImmutableArray(); | Preconditions = builder.Preconditions.ToImmutableArray(); | ||||
Attributes = builder.Attributes.ToImmutableArray(); | Attributes = builder.Attributes.ToImmutableArray(); | ||||
_reader = builder.TypeReader; | |||||
_readers = builder.TypeReaders; | |||||
} | } | ||||
public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, object arg, IServiceProvider services = null) | public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, object arg, IServiceProvider services = null) | ||||
@@ -59,10 +59,23 @@ namespace Discord.Commands | |||||
public async Task<TypeReaderResult> ParseAsync(ICommandContext context, string input, IServiceProvider services = null) | public async Task<TypeReaderResult> ParseAsync(ICommandContext context, string input, IServiceProvider services = null) | ||||
{ | { | ||||
services = services ?? EmptyServiceProvider.Instance; | services = services ?? EmptyServiceProvider.Instance; | ||||
return await _reader.ReadAsync(context, input, services).ConfigureAwait(false); | |||||
var failedResults = new List<TypeReaderResult>(); | |||||
foreach (var reader in _readers) | |||||
{ | |||||
var result = await reader.ReadAsync(context, input, services).ConfigureAwait(false); | |||||
if (result.IsSuccess) | |||||
return result; | |||||
failedResults.Add(result); | |||||
} | |||||
if (failedResults.Count == 1) | |||||
return failedResults[0]; | |||||
return TypeReaderResult.FromError(CommandError.Unsuccessful, "None of the registered TypeReaders could parse the input."); | |||||
} | } | ||||
public override string ToString() => Name; | public override string ToString() => Name; | ||||
private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}"; | private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}"; | ||||
} | } | ||||
} | |||||
} |