* add logic for passing the wild card captures into the context * move concrete impl of IRouteSegmentMatch to internal * Apply suggestions from code review Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * fix build errors * Apply suggestions from code review Co-authored-by: Armano den Boef <68127614+Rozen4334@users.noreply.github.com> Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> Co-authored-by: Armano den Boef <68127614+Rozen4334@users.noreply.github.com>tags/3.6.0
| @@ -0,0 +1,24 @@ | |||||
| using System.Collections.Generic; | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a container for temporarily storing CustomId wild card matches of a component. | |||||
| /// </summary> | |||||
| public interface IRouteMatchContainer | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the collection of captured route segments in this container. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A collection of captured route segments. | |||||
| ///</returns> | |||||
| IEnumerable<IRouteSegmentMatch> SegmentMatches { get; } | |||||
| /// <summary> | |||||
| /// Sets the <see cref="SegmentMatches"/> property of this container. | |||||
| /// </summary> | |||||
| /// <param name="segmentMatches">The collection of captured route segments.</param> | |||||
| void SetSegmentMatches(IEnumerable<IRouteSegmentMatch> segmentMatches); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents an object for storing a CustomId wild card match. | |||||
| /// </summary> | |||||
| public interface IRouteSegmentMatch | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the captured value of this wild card match. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// The value of this wild card. | |||||
| /// </returns> | |||||
| string Value { get; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| namespace Discord | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents an object for storing a CustomId wild card match. | |||||
| /// </summary> | |||||
| internal record RouteSegmentMatch : IRouteSegmentMatch | |||||
| { | |||||
| /// <inheritdoc/> | |||||
| public string Value { get; } | |||||
| public 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; | |||||
| } | } | ||||
| } | } | ||||
| @@ -775,6 +775,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); | ||||
| } | } | ||||
| @@ -819,9 +822,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) | ||||
| => _typeConverterMap.Get(type, services); | => _typeConverterMap.Get(type, services); | ||||
| @@ -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; | ||||