Table of Contents

Type Readers

Type Readers allow you to parse different types of arguments in your commands.

By default, the following Types are supported arguments:

  • bool
  • char
  • sbyte/byte
  • ushort/short
  • uint/int
  • ulong/long
  • float, double, decimal
  • string
  • enum
  • DateTime/DateTimeOffset/TimeSpan
  • Any nullable value-type (e.g. int?, bool?)
  • Any implementation of IChannel/IMessage/IUser/IRole

Creating a Type Reader

To create a TypeReader, create a new class that imports Discord and Discord.Commands and ensure the class inherits from TypeReader. Next, satisfy the TypeReader class by overriding the ReadAsync method.

Inside this Task, add whatever logic you need to parse the input string.

If you are able to successfully parse the input, return TypeReaderResult.FromSuccess with the parsed input, otherwise return TypeReaderResult.FromError and include an error message if necessary.

Note

Visual Studio can help you implement missing members from the abstract class by using the "Implement Abstract Class" IntelliSense hint.

Example - Creating a Type Reader

// Please note that the library already supports type reading
// primitive types such as bool. This example is merely used
// to demonstrate how one could write a simple TypeReader.
using Discord;
using Discord.Commands;

public class BooleanTypeReader : TypeReader
{
    public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
    {
        bool result;
        if (bool.TryParse(input, out result))
            return Task.FromResult(TypeReaderResult.FromSuccess(result));

        return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input could not be parsed as a boolean."));
    }
}

Registering a Type Reader

TypeReaders are not automatically discovered by the Command Service and must be explicitly added.

To register a TypeReader, invoke CommandService.AddTypeReader.

Important

TypeReaders must be added prior to module discovery, otherwise your TypeReaders may not work!

Example - Adding a Type Reader

public class CommandHandler
{
    private readonly CommandService _commands;
    private readonly DiscordSocketClient _client;
    private readonly IServiceProvider _services;

    public CommandHandler(CommandService commands, DiscordSocketClient client, IServiceProvider services)
    {
        _commands = commands;
        _client = client;
        _services = services;
    }

    public async Task SetupAsync()
    {
        _client.MessageReceived += CommandHandleAsync;

        // Add BooleanTypeReader to type read for the type "bool"
        _commands.AddTypeReader(typeof(bool), new BooleanTypeReader());

        // Then register the modules
        await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services);
    }

    public async Task CommandHandleAsync(SocketMessage msg)
    {
        // ...
    }
}