Compare commits
5 Commits
ee20c9c5ec
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d55c1c533 | |||
| e4ee03364c | |||
| c77b3e0742 | |||
| e391f0238a | |||
| 823169ca91 |
Submodule DTLib.Demystifier updated: bb96774c37...4eaade6e92
@@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!--package info-->
|
<!--package info-->
|
||||||
<PackageId>DTLib.Logging.Microsoft</PackageId>
|
<PackageId>DTLib.Logging.Microsoft</PackageId>
|
||||||
<Version>1.1.1</Version>
|
<Version>1.1.3</Version>
|
||||||
<Authors>Timerix</Authors>
|
<Authors>Timerix</Authors>
|
||||||
<Description>DTLib logger wrapper with dependency injection</Description>
|
<Description>DTLib logger wrapper with dependency injection</Description>
|
||||||
<RepositoryType>GIT</RepositoryType>
|
<RepositoryType>GIT</RepositoryType>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<!--compilation properties-->
|
<!--compilation properties-->
|
||||||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<!--language features-->
|
<!--language features-->
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Nullable>disable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<!--external dependencies-->
|
<!--external dependencies-->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!--DTLib dependencies-->
|
<!--DTLib dependencies-->
|
||||||
@@ -28,6 +28,6 @@
|
|||||||
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||||
<PackageReference Include="DTLib" Version="1.6.*" />
|
<PackageReference Include="DTLib" Version="1.7.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!--package info-->
|
<!--package info-->
|
||||||
<PackageId>DTLib.Web</PackageId>
|
<PackageId>DTLib.Web</PackageId>
|
||||||
<Version>1.3.0</Version>
|
<Version>1.4.0</Version>
|
||||||
<Authors>Timerix</Authors>
|
<Authors>Timerix</Authors>
|
||||||
<Description>HTTP Server with simple routing</Description>
|
<Description>HTTP Server with simple routing</Description>
|
||||||
<RepositoryType>GIT</RepositoryType>
|
<RepositoryType>GIT</RepositoryType>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<!--compilation properties-->
|
<!--compilation properties-->
|
||||||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||||
<!--language features-->
|
<!--language features-->
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
@@ -25,6 +25,6 @@
|
|||||||
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||||
<PackageReference Include="DTLib" Version="1.7.1" />
|
<PackageReference Include="DTLib" Version="1.7.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
namespace DTLib.Web;
|
namespace DTLib.Web;
|
||||||
|
|
||||||
/// <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods"/>
|
/// <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods"/>
|
||||||
public enum HttpMethod
|
[Flags]
|
||||||
|
public enum HttpMethod : ushort
|
||||||
{
|
{
|
||||||
GET,
|
NONE = 0,
|
||||||
POST,
|
GET = 1,
|
||||||
PUT,
|
POST = 2,
|
||||||
DELETE,
|
PUT = 4,
|
||||||
PATCH,
|
DELETE = 8,
|
||||||
HEAD,
|
PATCH = 16,
|
||||||
OPTIONS,
|
HEAD = 32,
|
||||||
TRACE,
|
OPTIONS = 64,
|
||||||
CONNECT
|
TRACE = 128,
|
||||||
|
CONNECT = 256,
|
||||||
|
ANY = 65535
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,5 @@ namespace DTLib.Web.Routes;
|
|||||||
|
|
||||||
public interface IRouter
|
public interface IRouter
|
||||||
{
|
{
|
||||||
Task<HttpStatusCode> Resolve(HttpListenerContext ctx, ContextLogger requestLogger);
|
Task Resolve(HttpListenerContext ctx, ContextLogger requestLogger);
|
||||||
}
|
}
|
||||||
@@ -3,42 +3,63 @@ namespace DTLib.Web.Routes;
|
|||||||
public class SimpleRouter : IRouter
|
public class SimpleRouter : IRouter
|
||||||
{
|
{
|
||||||
/// route for any url that doesn't have its own handler
|
/// route for any url that doesn't have its own handler
|
||||||
public IRouteHandler? DefaultRoute { get; set; }
|
public record RouteWithMethod(HttpMethod method, IRouteHandler routeHandler)
|
||||||
|
{
|
||||||
private readonly Dictionary<string, IRouteHandler> _routes = new();
|
public bool CheckMethod(HttpMethod requestMethod) => (requestMethod & method) != 0;
|
||||||
|
|
||||||
|
public bool CheckMethod(string requestMethodStr)
|
||||||
|
=> Enum.TryParse<HttpMethod>(requestMethodStr, out var requestMethod)
|
||||||
|
&& CheckMethod(requestMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<string, RouteWithMethod> _routes = new();
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public RouteWithMethod? DefaultRoute { get; set; }
|
||||||
|
|
||||||
public SimpleRouter(ILogger logger)
|
public SimpleRouter(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = new ContextLogger(nameof(SimpleRouter), logger);
|
_logger = new ContextLogger(nameof(SimpleRouter), logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MapRoute(string url, HttpMethod method, IRouteHandler route) => _routes.Add($"{url}:{method}", route);
|
public void MapRoute(string url, HttpMethod method, IRouteHandler route)
|
||||||
|
=> _routes.Add(url, new RouteWithMethod(method, route));
|
||||||
|
|
||||||
public void MapRoute(string url, HttpMethod method,
|
public void MapRoute(string url, HttpMethod method,
|
||||||
Func<HttpListenerContext, ContextLogger, Task<HttpStatusCode>> route)
|
Func<HttpListenerContext, ContextLogger, Task<HttpStatusCode>> route)
|
||||||
=> MapRoute(url, method, new DelegateRouteHandler(route));
|
=> MapRoute(url, method, new DelegateRouteHandler(route));
|
||||||
|
|
||||||
public async Task<HttpStatusCode> Resolve(HttpListenerContext ctx, ContextLogger requestLogger)
|
public async Task Resolve(HttpListenerContext ctx, ContextLogger requestLogger)
|
||||||
{
|
{
|
||||||
|
HttpStatusCode status = HttpStatusCode.InternalServerError;
|
||||||
string? requestPath = ctx.Request.Url?.AbsolutePath;
|
try
|
||||||
if (string.IsNullOrEmpty(requestPath))
|
|
||||||
requestPath = "/";
|
|
||||||
if (!_routes.TryGetValue($"{requestPath}:{ctx.Request.HttpMethod}", out var route))
|
|
||||||
route = DefaultRoute;
|
|
||||||
|
|
||||||
HttpStatusCode status;
|
|
||||||
if (route == null)
|
|
||||||
{
|
{
|
||||||
_logger.LogWarn(nameof(SimpleRouter), $"couldn't resolve request path {requestPath}");
|
string? requestPath = ctx.Request.Url?.AbsolutePath;
|
||||||
status = HttpStatusCode.NotFound;
|
if (string.IsNullOrEmpty(requestPath))
|
||||||
}
|
requestPath = "/";
|
||||||
else status = await route.HandleRequest(ctx, requestLogger);
|
|
||||||
|
if(!_routes.TryGetValue(requestPath!, out var routeWithMethod))
|
||||||
|
routeWithMethod = DefaultRoute;
|
||||||
|
|
||||||
ctx.Response.StatusCode = (int)status;
|
if (routeWithMethod is null)
|
||||||
await ctx.Response.OutputStream.FlushAsync();
|
{
|
||||||
ctx.Response.OutputStream.Close();
|
_logger.LogWarn(nameof(SimpleRouter),
|
||||||
return status;
|
$"couldn't resolve request path {ctx.Request.HttpMethod} {requestPath}");
|
||||||
|
status = HttpStatusCode.NotFound;
|
||||||
|
}
|
||||||
|
else if (!routeWithMethod.CheckMethod(ctx.Request.HttpMethod))
|
||||||
|
{
|
||||||
|
_logger.LogWarn(nameof(SimpleRouter),
|
||||||
|
$"received request with invalid method {ctx.Request.HttpMethod} {requestPath}");
|
||||||
|
status = HttpStatusCode.MethodNotAllowed;
|
||||||
|
}
|
||||||
|
else status = await routeWithMethod.routeHandler.HandleRequest(ctx, requestLogger);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ctx.Response.StatusCode = (int)status;
|
||||||
|
await ctx.Response.OutputStream.FlushAsync();
|
||||||
|
ctx.Response.OutputStream.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,9 +58,11 @@ public class WebApp
|
|||||||
requestLogger.LogInfo($"{ctx.Request.HttpMethod} {ctx.Request.RawUrl} from {ctx.Request.RemoteEndPoint}...");
|
requestLogger.LogInfo($"{ctx.Request.HttpMethod} {ctx.Request.RawUrl} from {ctx.Request.RemoteEndPoint}...");
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
var status = await _router.Resolve(ctx, requestLogger);
|
await _router.Resolve(ctx, requestLogger);
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
requestLogger.LogInfo($"responded {(int)status} ({status}) in {stopwatch.ElapsedMilliseconds}ms");
|
requestLogger.LogInfo($"responded {ctx.Response.StatusCode}" +
|
||||||
|
$" ({(HttpStatusCode)ctx.Response.StatusCode})" +
|
||||||
|
$" in {stopwatch.ElapsedMilliseconds}ms");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Submodule DTLib.XXHash updated: 9360dfe305...3e1a2c00e6
@@ -2,32 +2,135 @@ namespace DTLib.Console;
|
|||||||
|
|
||||||
public class LaunchArgumentParser
|
public class LaunchArgumentParser
|
||||||
{
|
{
|
||||||
public bool IsAllowedNoArguments;
|
public string HelpMessageHeader = "USAGE:";
|
||||||
|
public bool AllowedNoArguments;
|
||||||
|
public bool AllowedUnknownArguments;
|
||||||
|
// ReSharper disable once CollectionNeverQueried.Global
|
||||||
|
public readonly List<string> UnknownArguments = new();
|
||||||
|
|
||||||
private readonly Dictionary<string, LaunchArgument> argDict = new();
|
private readonly Dictionary<string, LaunchArgument> argDict = new();
|
||||||
private readonly List<LaunchArgument> argList = new();
|
private readonly List<LaunchArgument> argList = new();
|
||||||
|
|
||||||
public class ExitAfterHelpException : Exception
|
public LaunchArgumentParser()
|
||||||
{
|
{
|
||||||
internal ExitAfterHelpException() : base("your program can use this exception to exit after displaying help message")
|
var help = new LaunchArgument(new[] { "h", "help" },
|
||||||
{ }
|
"shows help message", HelpHandler);
|
||||||
|
Add(help);
|
||||||
|
var helpArg = new LaunchArgument(new[] { "ha", "helparg" },
|
||||||
|
"shows help message for specific argument",
|
||||||
|
HelpArgHandler, "argument");
|
||||||
|
Add(helpArg);
|
||||||
}
|
}
|
||||||
|
public LaunchArgumentParser(ICollection<LaunchArgument> arguments) : this() => WithArgs(arguments);
|
||||||
|
public LaunchArgumentParser(params LaunchArgument[] arguments) : this() => WithArgs(arguments);
|
||||||
|
|
||||||
|
public LaunchArgumentParser WithArgs(IEnumerable<LaunchArgument> args)
|
||||||
|
{
|
||||||
|
foreach (var arg in args)
|
||||||
|
Add(arg);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaunchArgumentParser WithArgs(params LaunchArgument[] args)
|
||||||
|
{
|
||||||
|
foreach (var arg in args)
|
||||||
|
Add(arg);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaunchArgumentParser WithHelpMessageHeader(string header)
|
||||||
|
{
|
||||||
|
HelpMessageHeader = header;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaunchArgumentParser AllowNoArguments()
|
||||||
|
{
|
||||||
|
AllowedNoArguments = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaunchArgumentParser AllowUnknownArguments()
|
||||||
|
{
|
||||||
|
AllowedUnknownArguments = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public string CreateHelpMessage()
|
public string CreateHelpMessage()
|
||||||
{
|
{
|
||||||
StringBuilder b = new();
|
StringBuilder b = new(HelpMessageHeader);
|
||||||
foreach (var arg in argList)
|
foreach (var arg in argList)
|
||||||
arg.AppendHelpInfo(b).Append('\n');
|
{
|
||||||
b.Remove(b.Length-1, 1);
|
b.Append('\n');
|
||||||
|
arg.AppendHelpInfo(b);
|
||||||
|
}
|
||||||
return b.ToString();
|
return b.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CreateHelpArgMessage(string argAlias)
|
public string CreateHelpArgMessage(string argAlias)
|
||||||
{
|
{
|
||||||
StringBuilder b = new();
|
StringBuilder b = new();
|
||||||
var arg = Parse(argAlias);
|
if(!TryParseArg(argAlias, out var arg))
|
||||||
|
throw new Exception($"unknown argument '{argAlias}'");
|
||||||
arg.AppendHelpInfo(b);
|
arg.AppendHelpInfo(b);
|
||||||
return b.ToString();
|
return b.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(LaunchArgument arg)
|
||||||
|
{
|
||||||
|
argList.Add(arg);
|
||||||
|
foreach (string alias in arg.Aliases)
|
||||||
|
argDict.Add(alias, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryParseArg(string argAlias, out LaunchArgument arg)
|
||||||
|
{
|
||||||
|
// different argument providing patterns
|
||||||
|
arg = null!;
|
||||||
|
return argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg) || // --arg
|
||||||
|
argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg) || // -arg
|
||||||
|
argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg); // /arg
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="args">program launch args</param>
|
||||||
|
/// <exception cref="Exception">argument {args[i]} should have a parameter after it</exception>
|
||||||
|
/// <exception cref="NullReferenceException">argument hasn't got any handlers</exception>
|
||||||
|
/// <exception cref="ExitAfterHelpException">happens after help message is displayed</exception>
|
||||||
|
public void ParseAndHandle(string[] args)
|
||||||
|
{
|
||||||
|
// show help message and throw ExitAfterHelpException
|
||||||
|
if (args.Length == 0 && !AllowedNoArguments)
|
||||||
|
HelpHandler();
|
||||||
|
|
||||||
|
List<LaunchArgument> execQueue = new();
|
||||||
|
|
||||||
|
for (int i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
if (!TryParseArg(args[i], out var arg))
|
||||||
|
{
|
||||||
|
if (!AllowedUnknownArguments)
|
||||||
|
throw new Exception($"unknown argument '{args[i]}'");
|
||||||
|
UnknownArguments.Add(args[i]);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < arg.Params.Length; j++)
|
||||||
|
{
|
||||||
|
if (++i >= args.Length)
|
||||||
|
throw new Exception(
|
||||||
|
$"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it");
|
||||||
|
arg.Params[j].Value = args[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
execQueue.Add(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ascending sort by priority
|
||||||
|
execQueue.Sort((a0, a1) => a0.Priority - a1.Priority);
|
||||||
|
// finally executing handlers
|
||||||
|
foreach (var a in execQueue)
|
||||||
|
a.Handle();
|
||||||
|
}
|
||||||
|
|
||||||
private void HelpHandler()
|
private void HelpHandler()
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(CreateHelpMessage());
|
System.Console.WriteLine(CreateHelpMessage());
|
||||||
@@ -40,83 +143,11 @@ public class LaunchArgumentParser
|
|||||||
throw new ExitAfterHelpException();
|
throw new ExitAfterHelpException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ExitAfterHelpException : Exception
|
||||||
public LaunchArgumentParser()
|
|
||||||
{
|
{
|
||||||
var help = new LaunchArgument(new[] { "h", "help" },
|
public ExitAfterHelpException()
|
||||||
"shows help message", HelpHandler);
|
: base("your program can use this exception to exit after displaying help message")
|
||||||
Add(help);
|
|
||||||
var helpArg = new LaunchArgument( new[]{ "ha", "helparg" },
|
|
||||||
"shows help message for particular argument",
|
|
||||||
HelpArgHandler, "argAlias");
|
|
||||||
Add(helpArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchArgumentParser AllowNoArguments()
|
|
||||||
{
|
|
||||||
IsAllowedNoArguments = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchArgumentParser(ICollection<LaunchArgument> arguments) : this()
|
|
||||||
{
|
|
||||||
foreach (var arg in arguments)
|
|
||||||
Add(arg);
|
|
||||||
}
|
|
||||||
public LaunchArgumentParser(params LaunchArgument[] arguments) : this()
|
|
||||||
{
|
|
||||||
foreach (var arg in arguments)
|
|
||||||
Add(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(LaunchArgument arg)
|
|
||||||
{
|
|
||||||
argList.Add(arg);
|
|
||||||
foreach (string alias in arg.Aliases)
|
|
||||||
argDict.Add(alias, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchArgument Parse(string argAlias)
|
|
||||||
{
|
|
||||||
// different argument providing patterns
|
|
||||||
if (!argDict.TryGetValue(argAlias, out var arg) && // arg
|
|
||||||
!(argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg)) && // --arg
|
|
||||||
!(argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg)) && // -arg
|
|
||||||
!(argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg))) // /arg
|
|
||||||
throw new Exception($"invalid argument: {argAlias}\n{CreateHelpMessage()}");
|
|
||||||
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <param name="args">program launch args</param>
|
|
||||||
/// <exception cref="Exception">argument {args[i]} should have a parameter after it</exception>
|
|
||||||
/// <exception cref="NullReferenceException">argument hasn't got any handlers</exception>
|
|
||||||
/// <exception cref="ExitAfterHelpException">happens after help message is displayed</exception>
|
|
||||||
public void ParseAndHandle(string[] args)
|
|
||||||
{
|
|
||||||
// show help message and throw ExitAfterHelpException
|
|
||||||
if (args.Length == 0 && !IsAllowedNoArguments)
|
|
||||||
HelpHandler();
|
|
||||||
|
|
||||||
List<LaunchArgument> execQueue = new();
|
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
|
||||||
{
|
{
|
||||||
LaunchArgument arg = Parse(args[i]);
|
|
||||||
for (int j = 0; j < arg.Params.Length; j++)
|
|
||||||
{
|
|
||||||
if (++i >= args.Length)
|
|
||||||
throw new Exception($"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it");
|
|
||||||
arg.Params[j].Value = args[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
execQueue.Add(arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ascending sort by priority
|
|
||||||
execQueue.Sort((a0, a1) => a0.Priority-a1.Priority);
|
|
||||||
// finally executing handlers
|
|
||||||
foreach (var a in execQueue)
|
|
||||||
a.Handle();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!--package info-->
|
<!--package info-->
|
||||||
<PackageId>DTLib</PackageId>
|
<PackageId>DTLib</PackageId>
|
||||||
<Version>1.7.1</Version>
|
<Version>1.7.4</Version>
|
||||||
<Authors>Timerix</Authors>
|
<Authors>Timerix</Authors>
|
||||||
<Description>Library for all my C# projects</Description>
|
<Description>Library for all my C# projects</Description>
|
||||||
<RepositoryType>GIT</RepositoryType>
|
<RepositoryType>GIT</RepositoryType>
|
||||||
@@ -31,6 +31,6 @@
|
|||||||
<ProjectReference Include="..\DTLib.Demystifier\DTLib.Demystifier.csproj" />
|
<ProjectReference Include="..\DTLib.Demystifier\DTLib.Demystifier.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||||
<PackageReference Include="DTLib.Demystifier" Version="1.1.0" />
|
<PackageReference Include="DTLib.Demystifier" Version="1.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user