namespace BotPages.Core.Routing;
using System.Text.RegularExpressions;
///
/// Реестр команд, доступных из любого места.
///
internal sealed class CommandsRegistry
{
private readonly List<(Regex pattern, Func handler)> _commands = new();
///
/// Зарегистрировать команду, ведущую на страницу.
///
public CommandsRegistry Map(string commandTemplate) where TPage : Page
{
var pattern = ToRegex(commandTemplate);
_commands.Add((pattern, (ctx, ct) => ctx.Navigation.GoToAsync(ctx, ct)));
return this;
}
///
/// Зарегистрировать команду с кастомным обработчиком.
///
public CommandsRegistry Map(string commandTemplate, Func handler)
{
var pattern = ToRegex(commandTemplate);
_commands.Add((pattern, handler));
return this;
}
///
/// Попробовать выполнить команду.
///
public bool TryDispatch(PageContext ctx, string command, CancellationToken ct, out Task? task)
{
foreach (var (pattern, handler) in _commands)
{
if (pattern.IsMatch(command))
{
task = handler(ctx, ct);
return true;
}
}
task = null;
return false;
}
private static Regex ToRegex(string template)
{
// Простейшее преобразование шаблона: "/open {page} {id?}" -> Regex
var escaped = Regex.Escape(template)
.Replace("\\{", "{").Replace("\\}", "}");
var pattern = "^" + escaped
.Replace("{page}", "(?\\S+)")
.Replace("{id?}", "(?\\S+)?") + "$";
return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}