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); } }