Skip to content

Commit 8379274

Browse files
authored
Added CommandParameterAttribute (#597)
1 parent cd69330 commit 8379274

4 files changed

Lines changed: 88 additions & 3 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace SampSharp.Entities.SAMP.Commands;
2+
3+
/// <summary>
4+
/// Specifies metadata for a command parameter, such as its display name and optional parser type.
5+
/// </summary>
6+
[AttributeUsage(AttributeTargets.Parameter)]
7+
public class CommandParameterAttribute : Attribute
8+
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="CommandParameterAttribute"/> class.
11+
/// </summary>
12+
public CommandParameterAttribute()
13+
{
14+
}
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="CommandParameterAttribute"/> class with a name and optional parser type.
18+
/// </summary>
19+
/// <param name="name">The display name of the command parameter or <see langword="null"/> to use the default name.</param>
20+
/// <param name="parserType">The type used to parse the parameter value, or <see langword="null"/> to use the default parser.</param>
21+
public CommandParameterAttribute(string? name, Type? parserType = null)
22+
{
23+
Name = name;
24+
ParserType = parserType;
25+
}
26+
27+
/// <summary>
28+
/// Gets or sets the display name of the command parameter.
29+
/// </summary>
30+
public string? Name { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the type used to parse the command parameter.
34+
/// </summary>
35+
public Type? ParserType { get; set; }
36+
}

src/SampSharp.OpenMp.Entities.Commands/Core/CommandScanner.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,16 @@ private static bool TryCollectParameters(ParameterInfo[] parameters, int prefixP
348348
{
349349
var param = parameters[i];
350350

351-
var paramName = param.Name ?? $"param{i}";
351+
var paramAtribute = param.GetCustomAttribute<CommandParameterAttribute>();
352+
353+
var paramName = paramAtribute?.Name ?? param.Name ?? $"param{i}";
352354

353355
// Try to get a parser for this parameter
354-
var parser = parserFactory.CreateParser(parameters, i);
356+
var parserInstance = paramAtribute?.ParserType is not null
357+
? Activator.CreateInstance(paramAtribute.ParserType)
358+
: null;
359+
360+
var parser = parserInstance as ICommandParameterParser ?? parserFactory.CreateParser(parameters, i);
355361

356362
if (parser == null)
357363
{

test/SampSharp.OpenMp.Entities.Commands.Tests/Core/CommandScannerTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ private class CommandWithSuffixSystem : ISystem
159159
public void HelpCommand(Player player) { }
160160
}
161161

162+
private class CommandWithCustomNameSystem : ISystem
163+
{
164+
[PlayerCommand]
165+
public void MessageCommand(Player player, [CommandParameter("custom")]string text) { }
166+
}
167+
162168
private class InvalidReturnTypeSystem : ISystem
163169
{
164170
// int is not a valid return type for player commands
@@ -259,6 +265,21 @@ public void ScanPlayerCommands_StripsSuffixFromMethodName()
259265
FindByName(registry, "help").ShouldNotBeNull();
260266
}
261267

268+
[Fact]
269+
public void ScanPlayerCommands_ProvidesCustomName()
270+
{
271+
var registry = CreateCommandRegistry();
272+
var scanner = CreateScanner(typeof(CommandWithCustomNameSystem));
273+
274+
scanner.ScanPlayerCommands(registry, CreateParserFactory());
275+
276+
FindByName(registry, "message")
277+
.ShouldNotBeNull()
278+
.ParsedParameters[0]
279+
.Name
280+
.ShouldBe("custom");
281+
}
282+
262283
[Fact]
263284
public void ScanPlayerCommands_ExtractsParsedParameters()
264285
{

test/TestMode.OpenMp.Entities/Systems/TestConsoleCommandsSystem.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,26 @@ public void AddCommand(int a, int b)
4343
{
4444
Console.WriteLine($"{a} + {b} = {a + b}");
4545
}
46-
}
46+
47+
[ConsoleCommand(Name = "double_number")]
48+
public void DoubleValueCommand([CommandParameter("value", typeof(DoubleIntParser))] int v)
49+
{
50+
Console.WriteLine(v);
51+
}
52+
53+
private class DoubleIntParser : ICommandParameterParser
54+
{
55+
private readonly IntParser _inner = new();
56+
57+
public bool TryParse(IServiceProvider services, ref StringSpan inputText, out object? result)
58+
{
59+
if (_inner.TryParse(services, ref inputText, out result) && result is int num)
60+
{
61+
result = num * 2;
62+
return true;
63+
}
64+
65+
return false;
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)