@@ -0,0 +1,21 @@ | |||||
using System.Collections.Generic; | |||||
namespace Discord | |||||
{ | |||||
/// <summary> | |||||
/// Represents a container for temporarily storing CustomId wild card matches of a command name. | |||||
/// </summary> | |||||
public interface IRouteMatchContainer | |||||
{ | |||||
/// <summary> | |||||
/// Gets the collection of the captured route segments. | |||||
/// </summary> | |||||
public IEnumerable<IRouteSegmentMatch> SegmentMatches { get; } | |||||
/// <summary> | |||||
/// Sets the <see cref="SegmentMatches"/> propert | |||||
/// </summary> | |||||
/// <param name="segmentMatches">The collection of captured route segments.</param> | |||||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches); | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
namespace Discord | |||||
{ | |||||
/// <summary> | |||||
/// Represents an object for storing CustomId a wild card match. | |||||
/// </summary> | |||||
public interface IRouteSegmentMatch | |||||
{ | |||||
/// <summary> | |||||
/// Gets the captured value. | |||||
/// </summary> | |||||
string Value { get; } | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
namespace Discord | |||||
{ | |||||
/// <summary> | |||||
/// Represents an object for storing CustomId wild card matches. | |||||
/// </summary> | |||||
public record RouteSegmentMatch : IRouteSegmentMatch | |||||
{ | |||||
/// <inheritdoc/> | |||||
public string Value { get; } | |||||
internal RouteSegmentMatch(string value) | |||||
{ | |||||
Value = value; | |||||
} | |||||
} | |||||
} |
@@ -1,7 +1,10 @@ | |||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
namespace Discord.Interactions | namespace Discord.Interactions | ||||
{ | { | ||||
/// <inheritdoc cref="IInteractionContext"/> | /// <inheritdoc cref="IInteractionContext"/> | ||||
public class InteractionContext : IInteractionContext | |||||
public class InteractionContext : IInteractionContext, IRouteMatchContainer | |||||
{ | { | ||||
/// <inheritdoc/> | /// <inheritdoc/> | ||||
public IDiscordClient Client { get; } | public IDiscordClient Client { get; } | ||||
@@ -13,6 +16,8 @@ namespace Discord.Interactions | |||||
public IUser User { get; } | public IUser User { get; } | ||||
/// <inheritdoc/> | /// <inheritdoc/> | ||||
public IDiscordInteraction Interaction { get; } | public IDiscordInteraction Interaction { get; } | ||||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | /// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | ||||
@@ -30,5 +35,12 @@ namespace Discord.Interactions | |||||
User = interaction.User; | User = interaction.User; | ||||
Interaction = interaction; | Interaction = interaction; | ||||
} | } | ||||
/// <inheritdoc/> | |||||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches) => SegmentMatches = segmentMatches.ToImmutableArray(); | |||||
//IRouteMatchContainer | |||||
/// <inheritdoc/> | |||||
IEnumerable<IRouteSegmentMatch> IRouteMatchContainer.SegmentMatches => SegmentMatches; | |||||
} | } | ||||
} | } |
@@ -677,7 +677,7 @@ namespace Discord.Interactions | |||||
public async Task<IResult> ExecuteCommandAsync (IInteractionContext context, IServiceProvider services) | public async Task<IResult> ExecuteCommandAsync (IInteractionContext context, IServiceProvider services) | ||||
{ | { | ||||
var interaction = context.Interaction; | var interaction = context.Interaction; | ||||
return interaction switch | return interaction switch | ||||
{ | { | ||||
ISlashCommandInteraction slashCommand => await ExecuteSlashCommandAsync(context, slashCommand, services).ConfigureAwait(false), | ISlashCommandInteraction slashCommand => await ExecuteSlashCommandAsync(context, slashCommand, services).ConfigureAwait(false), | ||||
@@ -734,6 +734,9 @@ namespace Discord.Interactions | |||||
await _componentCommandExecutedEvent.InvokeAsync(null, context, result).ConfigureAwait(false); | await _componentCommandExecutedEvent.InvokeAsync(null, context, result).ConfigureAwait(false); | ||||
return result; | return result; | ||||
} | } | ||||
SetMatchesIfApplicable(context, result); | |||||
return await result.Command.ExecuteAsync(context, services, result.RegexCaptureGroups).ConfigureAwait(false); | return await result.Command.ExecuteAsync(context, services, result.RegexCaptureGroups).ConfigureAwait(false); | ||||
} | } | ||||
@@ -780,9 +783,25 @@ namespace Discord.Interactions | |||||
await _componentCommandExecutedEvent.InvokeAsync(null, context, result).ConfigureAwait(false); | await _componentCommandExecutedEvent.InvokeAsync(null, context, result).ConfigureAwait(false); | ||||
return result; | return result; | ||||
} | } | ||||
SetMatchesIfApplicable(context, result); | |||||
return await result.Command.ExecuteAsync(context, services, result.RegexCaptureGroups).ConfigureAwait(false); | return await result.Command.ExecuteAsync(context, services, result.RegexCaptureGroups).ConfigureAwait(false); | ||||
} | } | ||||
private static void SetMatchesIfApplicable<T>(IInteractionContext context, SearchResult<T> searchResult) | |||||
where T : class, ICommandInfo | |||||
{ | |||||
if (!searchResult.Command.SupportsWildCards || context is not IRouteMatchContainer matchContainer) | |||||
return; | |||||
var matches = new RouteSegmentMatch[searchResult.RegexCaptureGroups.Length]; | |||||
for (var i = 0; i < searchResult.RegexCaptureGroups.Length; i++) | |||||
matches[i] = new RouteSegmentMatch(searchResult.RegexCaptureGroups[i]); | |||||
matchContainer.SetSegmentMatches(matches); | |||||
} | |||||
internal TypeConverter GetTypeConverter (Type type, IServiceProvider services = null) | internal TypeConverter GetTypeConverter (Type type, IServiceProvider services = null) | ||||
{ | { | ||||
if (_typeConverters.TryGetValue(type, out var specific)) | if (_typeConverters.TryGetValue(type, out var specific)) | ||||
@@ -1,4 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
namespace Discord.Rest | namespace Discord.Rest | ||||
@@ -6,7 +8,7 @@ namespace Discord.Rest | |||||
/// <summary> | /// <summary> | ||||
/// Represents a Rest based context of an <see cref="IDiscordInteraction"/>. | /// Represents a Rest based context of an <see cref="IDiscordInteraction"/>. | ||||
/// </summary> | /// </summary> | ||||
public class RestInteractionContext<TInteraction> : IRestInteractionContext | |||||
public class RestInteractionContext<TInteraction> : IRestInteractionContext, IRouteMatchContainer | |||||
where TInteraction : RestInteraction | where TInteraction : RestInteraction | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
@@ -45,6 +47,9 @@ namespace Discord.Rest | |||||
/// </remarks> | /// </remarks> | ||||
public Func<string, Task> InteractionResponseCallback { get; set; } | public Func<string, Task> InteractionResponseCallback { get; set; } | ||||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="RestInteractionContext{TInteraction}"/>. | /// Initializes a new <see cref="RestInteractionContext{TInteraction}"/>. | ||||
/// </summary> | /// </summary> | ||||
@@ -71,6 +76,13 @@ namespace Discord.Rest | |||||
InteractionResponseCallback = interactionResponseCallback; | InteractionResponseCallback = interactionResponseCallback; | ||||
} | } | ||||
/// <inheritdoc/> | |||||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches) => SegmentMatches = segmentMatches.ToImmutableArray(); | |||||
//IRouteMatchContainer | |||||
/// <inheritdoc/> | |||||
IEnumerable<IRouteSegmentMatch> IRouteMatchContainer.SegmentMatches => SegmentMatches; | |||||
// IInterationContext | // IInterationContext | ||||
/// <inheritdoc/> | /// <inheritdoc/> | ||||
IDiscordClient IInteractionContext.Client => Client; | IDiscordClient IInteractionContext.Client => Client; | ||||
@@ -1,11 +1,13 @@ | |||||
using Discord.WebSocket; | using Discord.WebSocket; | ||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
namespace Discord.Interactions | namespace Discord.Interactions | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Represents a Web-Socket based context of an <see cref="IDiscordInteraction"/>. | /// Represents a Web-Socket based context of an <see cref="IDiscordInteraction"/>. | ||||
/// </summary> | /// </summary> | ||||
public class SocketInteractionContext<TInteraction> : IInteractionContext | |||||
public class SocketInteractionContext<TInteraction> : IInteractionContext, IRouteMatchContainer | |||||
where TInteraction : SocketInteraction | where TInteraction : SocketInteraction | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
@@ -36,6 +38,9 @@ namespace Discord.Interactions | |||||
/// </summary> | /// </summary> | ||||
public TInteraction Interaction { get; } | public TInteraction Interaction { get; } | ||||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | /// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | ||||
/// </summary> | /// </summary> | ||||
@@ -50,6 +55,13 @@ namespace Discord.Interactions | |||||
Interaction = interaction; | Interaction = interaction; | ||||
} | } | ||||
/// <inheritdoc/> | |||||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches) => SegmentMatches = segmentMatches.ToImmutableArray(); | |||||
//IRouteMatchContainer | |||||
/// <inheritdoc/> | |||||
IEnumerable<IRouteSegmentMatch> IRouteMatchContainer.SegmentMatches => SegmentMatches; | |||||
// IInteractionContext | // IInteractionContext | ||||
/// <inheritdoc/> | /// <inheritdoc/> | ||||
IDiscordClient IInteractionContext.Client => Client; | IDiscordClient IInteractionContext.Client => Client; | ||||