Added support for concrete Rest/Socket/RPC classes in command params
This commit is contained in:
@@ -215,20 +215,6 @@ namespace Discord.Commands
|
|||||||
else
|
else
|
||||||
reader = service.GetDefaultTypeReader(paramType);
|
reader = service.GetDefaultTypeReader(paramType);
|
||||||
|
|
||||||
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.ParameterType = paramType;
|
||||||
builder.TypeReader = reader;
|
builder.TypeReader = reader;
|
||||||
}
|
}
|
||||||
@@ -239,10 +225,12 @@ namespace Discord.Commands
|
|||||||
var readers = service.GetTypeReaders(paramType);
|
var readers = service.GetTypeReaders(paramType);
|
||||||
TypeReader reader = null;
|
TypeReader reader = null;
|
||||||
if (readers != null)
|
if (readers != null)
|
||||||
|
{
|
||||||
if (readers.TryGetValue(typeReaderType, out reader))
|
if (readers.TryGetValue(typeReaderType, out reader))
|
||||||
return reader;
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
//could not find any registered type reader: try to create one
|
//We dont have a cached type reader, create one
|
||||||
reader = ReflectionUtils.CreateObject<TypeReader>(typeReaderType.GetTypeInfo(), service, DependencyMap.Empty);
|
reader = ReflectionUtils.CreateObject<TypeReader>(typeReaderType.GetTypeInfo(), service, DependencyMap.Empty);
|
||||||
service.AddTypeReader(paramType, reader);
|
service.AddTypeReader(paramType, reader);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Discord.Commands
|
|||||||
private readonly ConcurrentDictionary<Type, ModuleInfo> _typedModuleDefs;
|
private readonly ConcurrentDictionary<Type, ModuleInfo> _typedModuleDefs;
|
||||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>> _typeReaders;
|
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>> _typeReaders;
|
||||||
private readonly ConcurrentDictionary<Type, TypeReader> _defaultTypeReaders;
|
private readonly ConcurrentDictionary<Type, TypeReader> _defaultTypeReaders;
|
||||||
|
private readonly ImmutableList<Tuple<Type, Type>> _entityTypeReaders; //TODO: Candidate for C#7 Tuple
|
||||||
private readonly ConcurrentBag<ModuleInfo> _moduleDefs;
|
private readonly ConcurrentBag<ModuleInfo> _moduleDefs;
|
||||||
private readonly CommandMap _map;
|
private readonly CommandMap _map;
|
||||||
|
|
||||||
@@ -41,27 +42,16 @@ namespace Discord.Commands
|
|||||||
_map = new CommandMap(this);
|
_map = new CommandMap(this);
|
||||||
_typeReaders = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>>();
|
_typeReaders = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>>();
|
||||||
|
|
||||||
_defaultTypeReaders = new ConcurrentDictionary<Type, TypeReader>
|
_defaultTypeReaders = new ConcurrentDictionary<Type, TypeReader>();
|
||||||
{
|
|
||||||
[typeof(IMessage)] = new MessageTypeReader<IMessage>(),
|
|
||||||
[typeof(IUserMessage)] = new MessageTypeReader<IUserMessage>(),
|
|
||||||
[typeof(IChannel)] = new ChannelTypeReader<IChannel>(),
|
|
||||||
[typeof(IDMChannel)] = new ChannelTypeReader<IDMChannel>(),
|
|
||||||
[typeof(IGroupChannel)] = new ChannelTypeReader<IGroupChannel>(),
|
|
||||||
[typeof(IGuildChannel)] = new ChannelTypeReader<IGuildChannel>(),
|
|
||||||
[typeof(IMessageChannel)] = new ChannelTypeReader<IMessageChannel>(),
|
|
||||||
[typeof(IPrivateChannel)] = new ChannelTypeReader<IPrivateChannel>(),
|
|
||||||
[typeof(ITextChannel)] = new ChannelTypeReader<ITextChannel>(),
|
|
||||||
[typeof(IVoiceChannel)] = new ChannelTypeReader<IVoiceChannel>(),
|
|
||||||
|
|
||||||
[typeof(IRole)] = new RoleTypeReader<IRole>(),
|
|
||||||
|
|
||||||
[typeof(IUser)] = new UserTypeReader<IUser>(),
|
|
||||||
[typeof(IGroupUser)] = new UserTypeReader<IGroupUser>(),
|
|
||||||
[typeof(IGuildUser)] = new UserTypeReader<IGuildUser>(),
|
|
||||||
};
|
|
||||||
foreach (var type in PrimitiveParsers.SupportedTypes)
|
foreach (var type in PrimitiveParsers.SupportedTypes)
|
||||||
_defaultTypeReaders[type] = PrimitiveTypeReader.Create(type);
|
_defaultTypeReaders[type] = PrimitiveTypeReader.Create(type);
|
||||||
|
|
||||||
|
var entityTypeReaders = ImmutableList.CreateBuilder<Tuple<Type, Type>>();
|
||||||
|
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IMessage), typeof(MessageTypeReader<>)));
|
||||||
|
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IChannel), typeof(ChannelTypeReader<>)));
|
||||||
|
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IRole), typeof(RoleTypeReader<>)));
|
||||||
|
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IUser), typeof(UserTypeReader<>)));
|
||||||
|
_entityTypeReaders = entityTypeReaders.ToImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Modules
|
//Modules
|
||||||
@@ -208,11 +198,32 @@ namespace Discord.Commands
|
|||||||
TypeReader reader;
|
TypeReader reader;
|
||||||
if (_defaultTypeReaders.TryGetValue(type, out reader))
|
if (_defaultTypeReaders.TryGetValue(type, out reader))
|
||||||
return reader;
|
return reader;
|
||||||
|
var typeInfo = type.GetTypeInfo();
|
||||||
|
|
||||||
|
//Is this an enum?
|
||||||
|
if (typeInfo.IsEnum)
|
||||||
|
{
|
||||||
|
reader = EnumTypeReader.GetReader(type);
|
||||||
|
_defaultTypeReaders[type] = reader;
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Is this an entity?
|
||||||
|
for (int i = 0; i < _entityTypeReaders.Count; i++)
|
||||||
|
{
|
||||||
|
if (type == _entityTypeReaders[i].Item1 || typeInfo.ImplementedInterfaces.Contains(_entityTypeReaders[i].Item1))
|
||||||
|
{
|
||||||
|
reader = Activator.CreateInstance(_entityTypeReaders[i].Item2.MakeGenericType(type)) as TypeReader;
|
||||||
|
_defaultTypeReaders[type] = reader;
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Execution
|
//Execution
|
||||||
public SearchResult Search(CommandContext context, int argPos) => Search(context, context.Message.Content.Substring(argPos));
|
public SearchResult Search(CommandContext context, int argPos)
|
||||||
|
=> Search(context, context.Message.Content.Substring(argPos));
|
||||||
public SearchResult Search(CommandContext context, string input)
|
public SearchResult Search(CommandContext context, string input)
|
||||||
{
|
{
|
||||||
string searchInput = _caseSensitive ? input : input.ToLowerInvariant();
|
string searchInput = _caseSensitive ? input : input.ToLowerInvariant();
|
||||||
|
|||||||
Reference in New Issue
Block a user