Merge pull request #364 from FiniteReality/feature/parameter-tweaks
Parameter preconditions and typereader overriding
This commit is contained in:
@@ -182,6 +182,10 @@ namespace Discord.Commands
|
||||
// TODO: C#7 type switch
|
||||
if (attribute is SummaryAttribute)
|
||||
builder.Summary = (attribute as SummaryAttribute).Text;
|
||||
else if (attribute is OverrideTypeReaderAttribute)
|
||||
builder.TypeReader = GetTypeReader(service, paramType, (attribute as OverrideTypeReaderAttribute).TypeReader);
|
||||
else if (attribute is ParameterPreconditionAttribute)
|
||||
builder.AddPrecondition(attribute as ParameterPreconditionAttribute);
|
||||
else if (attribute is ParamArrayAttribute)
|
||||
{
|
||||
builder.IsMultiple = true;
|
||||
@@ -196,23 +200,42 @@ namespace Discord.Commands
|
||||
}
|
||||
}
|
||||
|
||||
var reader = service.GetTypeReader(paramType);
|
||||
if (reader == null)
|
||||
if (builder.TypeReader == null)
|
||||
{
|
||||
var paramTypeInfo = paramType.GetTypeInfo();
|
||||
if (paramTypeInfo.IsEnum)
|
||||
{
|
||||
reader = EnumTypeReader.GetReader(paramType);
|
||||
service.AddTypeReader(paramType, reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"{paramType.FullName} is not supported as a command parameter, are you missing a TypeReader?");
|
||||
}
|
||||
}
|
||||
var reader = service.GetDefaultTypeReader(paramType);
|
||||
|
||||
builder.ParameterType = paramType;
|
||||
builder.TypeReader = reader;
|
||||
if (reader == null)
|
||||
{
|
||||
var paramTypeInfo = paramType.GetTypeInfo();
|
||||
if (paramTypeInfo.IsEnum)
|
||||
{
|
||||
reader = EnumTypeReader.GetReader(paramType);
|
||||
service.AddTypeReader(paramType, reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"{paramType.FullName} is not supported as a command parameter, are you missing a TypeReader?");
|
||||
}
|
||||
}
|
||||
|
||||
builder.ParameterType = paramType;
|
||||
builder.TypeReader = reader;
|
||||
}
|
||||
}
|
||||
|
||||
private static TypeReader GetTypeReader(CommandService service, Type paramType, Type typeReaderType)
|
||||
{
|
||||
var readers = service.GetTypeReaders(paramType);
|
||||
TypeReader reader = null;
|
||||
if (readers != null)
|
||||
if (readers.TryGetValue(typeReaderType, out reader))
|
||||
return reader;
|
||||
|
||||
//could not find any registered type reader: try to create one
|
||||
reader = ReflectionUtils.CreateObject<TypeReader>(typeReaderType.GetTypeInfo(), service, DependencyMap.Empty);
|
||||
service.AddTypeReader(paramType, reader);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
private static bool IsValidModuleDefinition(TypeInfo typeInfo)
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.Commands.Builders
|
||||
{
|
||||
public class ParameterBuilder
|
||||
{
|
||||
private readonly List<ParameterPreconditionAttribute> _preconditions;
|
||||
|
||||
public CommandBuilder Command { get; }
|
||||
public string Name { get; internal set; }
|
||||
public Type ParameterType { get; internal set; }
|
||||
@@ -16,16 +21,20 @@ namespace Discord.Commands.Builders
|
||||
public object DefaultValue { get; set; }
|
||||
public string Summary { get; set; }
|
||||
|
||||
public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions;
|
||||
|
||||
//Automatic
|
||||
internal ParameterBuilder(CommandBuilder command)
|
||||
{
|
||||
_preconditions = new List<ParameterPreconditionAttribute>();
|
||||
|
||||
Command = command;
|
||||
}
|
||||
//User-defined
|
||||
internal ParameterBuilder(CommandBuilder command, string name, Type type)
|
||||
: this(command)
|
||||
{
|
||||
Preconditions.NotNull(name, nameof(name));
|
||||
Discord.Preconditions.NotNull(name, nameof(name));
|
||||
|
||||
Name = name;
|
||||
SetType(type);
|
||||
@@ -33,7 +42,11 @@ namespace Discord.Commands.Builders
|
||||
|
||||
internal void SetType(Type type)
|
||||
{
|
||||
TypeReader = Command.Module.Service.GetTypeReader(type);
|
||||
var readers = Command.Module.Service.GetTypeReaders(type);
|
||||
if (readers == null)
|
||||
throw new InvalidOperationException($"{type} does not have a TypeReader registered for it");
|
||||
|
||||
TypeReader = readers.FirstOrDefault().Value;
|
||||
|
||||
if (type.GetTypeInfo().IsValueType)
|
||||
DefaultValue = Activator.CreateInstance(type);
|
||||
@@ -49,7 +62,7 @@ namespace Discord.Commands.Builders
|
||||
}
|
||||
public ParameterBuilder WithDefault(object defaultValue)
|
||||
{
|
||||
DefaultValue = defaultValue;
|
||||
DefaultValue = defaultValue;
|
||||
return this;
|
||||
}
|
||||
public ParameterBuilder WithIsOptional(bool isOptional)
|
||||
@@ -68,6 +81,12 @@ namespace Discord.Commands.Builders
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParameterBuilder AddPrecondition(ParameterPreconditionAttribute precondition)
|
||||
{
|
||||
_preconditions.Add(precondition);
|
||||
return this;
|
||||
}
|
||||
|
||||
internal ParameterInfo Build(CommandInfo info)
|
||||
{
|
||||
if (TypeReader == null)
|
||||
|
||||
Reference in New Issue
Block a user