Browse Source

Allow parameters to store the collection of TypeReaders for their type

pull/935/head
Joe4evr 7 years ago
parent
commit
ff5d1aae64
3 changed files with 32 additions and 25 deletions
  1. +4
    -11
      src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs
  2. +10
    -9
      src/Discord.Net.Commands/Builders/ParameterBuilder.cs
  3. +18
    -5
      src/Discord.Net.Commands/Info/ParameterInfo.cs

+ 4
- 11
src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using System.Threading.Tasks;

@@ -245,7 +246,7 @@ namespace Discord.Commands
builder.Summary = summary.Text;
break;
case OverrideTypeReaderAttribute typeReader:
builder.TypeReader = GetTypeReader(service, paramType, typeReader.TypeReader);
builder.TypeReaders = ImmutableList.Create(GetTypeReader(service, paramType, typeReader.TypeReader));
break;
case ParamArrayAttribute _:
builder.IsMultiple = true;
@@ -271,17 +272,9 @@ namespace Discord.Commands

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();
}
}



+ 10
- 9
src/Discord.Net.Commands/Builders/ParameterBuilder.cs View File

@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;

using System.Collections.Generic;

namespace Discord.Commands.Builders
{
@@ -15,7 +16,7 @@ namespace Discord.Commands.Builders
public string Name { 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 IsRemainder { get; set; }
public bool IsMultiple { get; set; }
@@ -45,13 +46,13 @@ namespace Discord.Commands.Builders

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
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}");

if (type.GetTypeInfo().IsValueType)
@@ -100,10 +101,10 @@ namespace Discord.Commands.Builders

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");

return new ParameterInfo(this, info, Command.Module.Service);
}
}
}
}

+ 18
- 5
src/Discord.Net.Commands/Info/ParameterInfo.cs View File

@@ -1,15 +1,15 @@
using Discord.Commands.Builders;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Discord.Commands.Builders;

namespace Discord.Commands
{
public class ParameterInfo
{
private readonly TypeReader _reader;
private readonly IReadOnlyCollection<TypeReader> _readers;

public CommandInfo Command { get; }
public string Name { get; }
@@ -39,7 +39,7 @@ namespace Discord.Commands
Preconditions = builder.Preconditions.ToImmutableArray();
Attributes = builder.Attributes.ToImmutableArray();

_reader = builder.TypeReader;
_readers = builder.TypeReaders;
}

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)
{
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;
private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}";
}
}
}

Loading…
Cancel
Save