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




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

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

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

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

Loading…
Cancel
Save