@@ -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 | |||
{ | |||
/// <inheritdoc cref="IInteractionContext"/> | |||
public class InteractionContext : IInteractionContext | |||
public class InteractionContext : IInteractionContext, IRouteMatchContainer | |||
{ | |||
/// <inheritdoc/> | |||
public IDiscordClient Client { get; } | |||
@@ -13,6 +16,8 @@ namespace Discord.Interactions | |||
public IUser User { get; } | |||
/// <inheritdoc/> | |||
public IDiscordInteraction Interaction { get; } | |||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||
/// <summary> | |||
/// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | |||
@@ -30,5 +35,12 @@ namespace Discord.Interactions | |||
User = interaction.User; | |||
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) | |||
{ | |||
var interaction = context.Interaction; | |||
return interaction switch | |||
{ | |||
ISlashCommandInteraction slashCommand => await ExecuteSlashCommandAsync(context, slashCommand, services).ConfigureAwait(false), | |||
@@ -734,6 +734,9 @@ namespace Discord.Interactions | |||
await _componentCommandExecutedEvent.InvokeAsync(null, context, result).ConfigureAwait(false); | |||
return result; | |||
} | |||
SetMatchesIfApplicable(context, result); | |||
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); | |||
return result; | |||
} | |||
SetMatchesIfApplicable(context, result); | |||
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) | |||
{ | |||
if (_typeConverters.TryGetValue(type, out var specific)) | |||
@@ -1,4 +1,6 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Threading.Tasks; | |||
namespace Discord.Rest | |||
@@ -6,7 +8,7 @@ namespace Discord.Rest | |||
/// <summary> | |||
/// Represents a Rest based context of an <see cref="IDiscordInteraction"/>. | |||
/// </summary> | |||
public class RestInteractionContext<TInteraction> : IRestInteractionContext | |||
public class RestInteractionContext<TInteraction> : IRestInteractionContext, IRouteMatchContainer | |||
where TInteraction : RestInteraction | |||
{ | |||
/// <summary> | |||
@@ -45,6 +47,9 @@ namespace Discord.Rest | |||
/// </remarks> | |||
public Func<string, Task> InteractionResponseCallback { get; set; } | |||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||
/// <summary> | |||
/// Initializes a new <see cref="RestInteractionContext{TInteraction}"/>. | |||
/// </summary> | |||
@@ -71,6 +76,13 @@ namespace Discord.Rest | |||
InteractionResponseCallback = interactionResponseCallback; | |||
} | |||
/// <inheritdoc/> | |||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches) => SegmentMatches = segmentMatches.ToImmutableArray(); | |||
//IRouteMatchContainer | |||
/// <inheritdoc/> | |||
IEnumerable<IRouteSegmentMatch> IRouteMatchContainer.SegmentMatches => SegmentMatches; | |||
// IInterationContext | |||
/// <inheritdoc/> | |||
IDiscordClient IInteractionContext.Client => Client; | |||
@@ -1,11 +1,13 @@ | |||
using Discord.WebSocket; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
namespace Discord.Interactions | |||
{ | |||
/// <summary> | |||
/// Represents a Web-Socket based context of an <see cref="IDiscordInteraction"/>. | |||
/// </summary> | |||
public class SocketInteractionContext<TInteraction> : IInteractionContext | |||
public class SocketInteractionContext<TInteraction> : IInteractionContext, IRouteMatchContainer | |||
where TInteraction : SocketInteraction | |||
{ | |||
/// <summary> | |||
@@ -36,6 +38,9 @@ namespace Discord.Interactions | |||
/// </summary> | |||
public TInteraction Interaction { get; } | |||
/// <inheritdoc cref="IRouteMatchContainer.SegmentMatches"/> | |||
public IReadOnlyCollection<IRouteSegmentMatch> SegmentMatches { get; private set; } | |||
/// <summary> | |||
/// Initializes a new <see cref="SocketInteractionContext{TInteraction}"/>. | |||
/// </summary> | |||
@@ -50,6 +55,13 @@ namespace Discord.Interactions | |||
Interaction = interaction; | |||
} | |||
/// <inheritdoc/> | |||
public void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches) => SegmentMatches = segmentMatches.ToImmutableArray(); | |||
//IRouteMatchContainer | |||
/// <inheritdoc/> | |||
IEnumerable<IRouteSegmentMatch> IRouteMatchContainer.SegmentMatches => SegmentMatches; | |||
// IInteractionContext | |||
/// <inheritdoc/> | |||
IDiscordClient IInteractionContext.Client => Client; | |||